<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-04-10T05:57:57+00:00</updated><id>/feed.xml</id><title type="html">Yuru Shao’s homepage</title><subtitle>Powered by Jekyll with the Minima theme.</subtitle><author><name>Yuru Shao</name></author><entry><title type="html">Using latexdiff and latexpand for marking changes between two paper versions</title><link href="/2019/02/15/latexdiff-and-latexpand.html" rel="alternate" type="text/html" title="Using latexdiff and latexpand for marking changes between two paper versions" /><published>2019-02-15T00:00:00+00:00</published><updated>2019-02-15T00:00:00+00:00</updated><id>/2019/02/15/latexdiff-and-latexpand</id><content type="html" xml:base="/2019/02/15/latexdiff-and-latexpand.html"><![CDATA[<p>I recently used <code class="language-plaintext highlighter-rouge">latexdiff</code> during the paper shepherding process. I found it very useful for highlighting changes between different papers versions (basically the submission version and the revised version shared to the shepherd).</p>

<p>Here’s a thorough tutorial on <code class="language-plaintext highlighter-rouge">latexdiff</code>: <a href="https://www.overleaf.com/learn/latex/Articles/Using_Latexdiff_For_Marking_Changes_To_Tex_Documents">https://www.overleaf.com/learn/latex/Articles/Using_Latexdiff_For_Marking_Changes_To_Tex_Documents</a>.</p>

<p>I only have one more thing to add. If you have multiple tex files for your paper, before calling <code class="language-plaintext highlighter-rouge">latexdiff</code> you need to run <code class="language-plaintext highlighter-rouge">latexpand</code> on your master tex (say <code class="language-plaintext highlighter-rouge">paper_master.tex</code>).</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd paper_dir # latexpand doesn't work outside your paper folder
$ latexpand paper_master.tex &gt; paper_expanded.tex
</code></pre></div></div>

<p>Once you have <code class="language-plaintext highlighter-rouge">paper_old_expanded.tex</code> and <code class="language-plaintext highlighter-rouge">paper_new_expanded.tex</code>, you need to run</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ latexdiff paper_old_expanded.tex paper_new_expanded &gt; paper_diff.tex
</code></pre></div></div>

<p>Then you can compile <code class="language-plaintext highlighter-rouge">paper_diff.tex</code> the same way of compiling <code class="language-plaintext highlighter-rouge">paper_master.tex</code>. This means <code class="language-plaintext highlighter-rouge">paper.diff</code> requires the same resources, such as embedded source code files, figures, etc.</p>

<h1 id="tips">Tips</h1>
<p>If you cannot compile <code class="language-plaintext highlighter-rouge">paper_diff.tex</code>, try the following solutions (and cross your fingers).</p>

<ol>
  <li>Using <code class="language-plaintext highlighter-rouge">xelatex</code> instead of <code class="language-plaintext highlighter-rouge">latex</code> or <code class="language-plaintext highlighter-rouge">pdflatex</code>. I don’t know why but it appears to me that <code class="language-plaintext highlighter-rouge">xelatex</code> is more robust.</li>
  <li>Replacing the default <code class="language-plaintext highlighter-rouge">latexdiff</code> preamble with <a href="/assets/txt/latexdiff_preamble.txt">these lines</a>.</li>
</ol>]]></content><author><name>Yuru Shao</name></author><category term="" /><category term="" /><summary type="html"><![CDATA[I recently used latexdiff during the paper shepherding process. I found it very useful for highlighting changes between different papers versions (basically the submission version and the revised version shared to the shepherd).]]></summary></entry><entry><title type="html">Learn PLC Programming with RSLogix Emulate 500</title><link href="/tutorial/2018/05/02/start-plc-programming-with-rslogix.html" rel="alternate" type="text/html" title="Learn PLC Programming with RSLogix Emulate 500" /><published>2018-05-02T00:00:00+00:00</published><updated>2018-05-02T00:00:00+00:00</updated><id>/tutorial/2018/05/02/start-plc-programming-with-rslogix</id><content type="html" xml:base="/tutorial/2018/05/02/start-plc-programming-with-rslogix.html"><![CDATA[<p>A programmable logic controller (PLC), or programmable controller is an industrial digital computer which has been ruggedized and adapted for the control of manufacturing processes, such as assembly lines, or robotic devices, or any activity that requires high reliability control and ease of programming and process fault diagnosis [1].</p>

<p><a href="http://www.openplcproject.com/">OpenPLC</a> is good for hobbyists and for research purposes. In this post, I’m using Rockwell Automation products, which are closer to what people use in real factories.</p>

<ol>
  <li>RSLogix Emulate 500 (<a href="https://compatibility.rockwellautomation.com/Pages/MultiProductFindDownloads.aspx?crumb=112&amp;mode=3&amp;refSoft=1&amp;versions=50059">download</a>): the PLC emulator software.</li>
  <li>RSLogix Micro Starter Lite w/o RSLinx (<a href="https://compatibility.rockwellautomation.com/pages/search.aspx?crumb=117&amp;q=RSLogix%20Micro%20Starter%20Lite%20w/o%20RSLinx%20EN">download</a>): the tool for writing PLC programs with ladder logic.</li>
  <li>RSLinx Classic Lite (<a href="https://compatibility.rockwellautomation.com/Pages/MultiProductFindDownloads.aspx?crumb=112&amp;mode=3&amp;refSoft=1&amp;versions=51543">download</a>): for communications among Rockwell networks and devices.</li>
</ol>

<p>This this <a href="https://www.youtube.com/watch?v=tJLEx44HacY">video</a> shows how to download the programs.</p>

<p>These programs are Windows-only, and remember to run them with admin privileges (aka, <code class="language-plaintext highlighter-rouge">as an administrator</code>).</p>

<h1 id="configure-driver">Configure Driver</h1>

<p>RSLinx Classic Lite comes with a bunch of different drivers. By configuring the emulator driver we let our working PC know how to communicate with the emulator. The <code class="language-plaintext highlighter-rouge">Station Number</code> of the PC is <code class="language-plaintext highlighter-rouge">0</code>, <code class="language-plaintext highlighter-rouge">Station Name</code> could be whatever string we like.</p>

<p><img src="/assets/images/20180502/RSLinx_configure_driver.gif" alt="" /></p>

<h1 id="write-a-simple-program">Write a Simple Program</h1>

<p>We write PLC programs using ladder logic in RSLogix Micro.</p>

<p><img src="/assets/images/20180502/simple_ladder_logic.gif" alt="" /></p>

<h1 id="set-up-the-emulator">Set Up the Emulator</h1>

<p>We assign <code class="language-plaintext highlighter-rouge">1</code> to the emulator’s <code class="language-plaintext highlighter-rouge">Station #</code>, as <code class="language-plaintext highlighter-rouge">0</code> has been taken by the PC.</p>

<p><img src="/assets/images/20180502/start_emulator.gif" alt="" /></p>

<p>After the emulator is set up, RSLinx is able to detect it.</p>

<p><img src="/assets/images/20180502/emulator_ready.png" alt="" /></p>

<h1 id="download-program-to-plc">Download Program to PLC</h1>

<p><img src="/assets/images/20180502/download_to_plc.gif" alt="" /></p>

<p>By toggling the input <code class="language-plaintext highlighter-rouge">I:0/0</code>, the output bit <code class="language-plaintext highlighter-rouge">O:0/0</code> changes accordingly.</p>

<h1 id="references">References</h1>

<p>[1] https://en.wikipedia.org/wiki/Programmable_logic_controller</p>

<p>[2] https://www.youtube.com/watch?v=t9JoLjiwjtw</p>]]></content><author><name>Yuru Shao</name></author><category term="Tutorial" /><category term="PLC" /><summary type="html"><![CDATA[A programmable logic controller (PLC), or programmable controller is an industrial digital computer which has been ruggedized and adapted for the control of manufacturing processes, such as assembly lines, or robotic devices, or any activity that requires high reliability control and ease of programming and process fault diagnosis [1].]]></summary></entry><entry><title type="html">Mobile Advertising and Tracking Ecosystem</title><link href="/tech/2017/12/28/app-trackers.html" rel="alternate" type="text/html" title="Mobile Advertising and Tracking Ecosystem" /><published>2017-12-28T00:00:00+00:00</published><updated>2017-12-28T00:00:00+00:00</updated><id>/tech/2017/12/28/app-trackers</id><content type="html" xml:base="/tech/2017/12/28/app-trackers.html"><![CDATA[<p>I recently read a paper that has been accepted into NDSS 2018. <a href="https://www.haystack.mobi/papers/ndss18_ats.pdf">This paper</a> presents some interesting insights into the mobile advertising and tracking ecosystem and its stakeholders.</p>

<p>The authors developed automated methods to detect third-party advertising and tracking services (ATS) <em>at the traffic level</em>. User data were collected with <a href="https://play.google.com/store/apps/details?id=edu.berkeley.icsi.haystack">Lumen privacy monitor</a>, which is an Android app runs locally on the device and intercepts all network traffic over both WiFi and mobile network. It’s essentially a VPN proxy that sits between apps and network interfaces. The app itself doesn’t need root access, but it asks the user to grant it the VPN permission. In summary, with Lumen privacy monitor, the authors collected 8.5M flows from 14,599 apps to 40,533 unique fully-qualified domain names (FQDNs) with 13,454 unique second-level domains (SLDs). After classification, 2,121 ATSes (233 are previously unknown) and 730 ATS-capable services were identified. By characterizing ATS domains, the paper uncovers business relationships between service providers. <strong>8/10 top organizations reserve the right to sell or share data with other organizations, while all of them reserve the right to share data with their subsidiaries.</strong></p>

<h1 id="third-party-domains">Third-party domains</h1>

<p>This paper makes a reasonable assumption that first-party domains are considered to be trusted by users when they install apps. Therefore, only third-party domains are in the scope of study. Two categories of third-party domains are defined:</p>

<ol>
  <li>ATS domains: ones that belong to  companies whose primary service is providing advertising and tracking services.</li>
  <li>ATS-capable domains (ATS-C): domains that collect tracking information, but whose primary service is not specifically providing ads and analytics to app developers.</li>
</ol>

<p>An example of ATS-C is a map API for collecting location data and other information to provide area maps and directions. It doesn’t necessarily rely on tracking users for monetizing their service. However, ATS-Cs can possibly later share data with other parties.</p>

<h1 id="domain-classification">Domain classification</h1>
<p>The goal of domain classification is to identify third-party domains, then identifying ATS-related domains (i.e., ATSes and ATS-Cs).</p>

<p>Existing ATS blacklists and URL categorization services both have limitations. Rather than completely relying them, the authors use them to train, test, and curate their domain classifier and results.
Their approach consists of three major steps: (1) identifying third-party domains, (2) classifying third-party domains to identify ATS domains (with manual validation of 200 domains), and (3) labeling domains that receive unique identifiers from user devices but were not identified in the previous step as ATS-C</p>

<h1 id="findings">Findings</h1>

<p><strong>The mobile ATS ecosystem</strong></p>

<p>The paper reports that 292 parent organizations own nearly 2,000 ATS and ATS-C domains. Alphabet (Google’s parent company) has penetration in over 73% of all measured apps with ownership of only 3.6% of all ATS/ATS-C domains. Domains belonging to the same organization are more likely to co-occur.
<!--
ATS domain co-occurrences
Jaccard similarity: JS(dom_a, dom_b) = (apps_a AND apps_b)/(apps_a OR apps_b)
--></p>

<p><strong>Application characteristics</strong></p>

<p>The numbers of trackers: free apps with in-app purchases  &gt; free apps &gt; paid apps. Apps with in-app purchases may have more aggressive monetization strategies.
Games and educational apps are the two categories with the highest number of ATS/ATS-C domains
Cross-device tracking is widespread: 39% identified ATSes are present as third-parties in at least one of the Alexa top 1000 websites.</p>

<p><strong>Regulatory challenge</strong></p>

<p>ATS services in US have disproportionately higher access to ATS related data: 40% ATS servers are the end of 73% ATS-related flows. Flows of UIDs from nations in the European Union mostly go to US (89.27%) and China (4.02%).  They are likely to be the most impacted by the upcoming regulations.</p>]]></content><author><name>Yuru Shao</name></author><category term="Tech" /><category term="Privacy" /><category term="Paper" /><summary type="html"><![CDATA[I recently read a paper that has been accepted into NDSS 2018. This paper presents some interesting insights into the mobile advertising and tracking ecosystem and its stakeholders.]]></summary></entry><entry><title type="html">Xposed cannot find my module’s class</title><link href="/tech/2016/05/13/Xposed-cannot-find-class.html" rel="alternate" type="text/html" title="Xposed cannot find my module’s class" /><published>2016-05-13T00:00:00+00:00</published><updated>2016-05-13T00:00:00+00:00</updated><id>/tech/2016/05/13/Xposed-cannot-find-class</id><content type="html" xml:base="/tech/2016/05/13/Xposed-cannot-find-class.html"><![CDATA[<p>If you’re pretty sure that you did everything right but Xposed still cannot load the class of your module, you need to check the apk file generated by Android Studio.</p>

<p>In my case, if my module’s apk has multiple dex inside, Xposed cannot find the class. After forcing Android Studio to output an apk having only one classes.dex, it works like a charm.</p>]]></content><author><name>Yuru Shao</name></author><category term="Tech" /><category term="Android" /><category term="Xposed" /><summary type="html"><![CDATA[If you’re pretty sure that you did everything right but Xposed still cannot load the class of your module, you need to check the apk file generated by Android Studio.]]></summary></entry><entry><title type="html">Error:only position independent executables (PIE) are supported</title><link href="/tech/2016/03/14/Android-PIE.html" rel="alternate" type="text/html" title="Error:only position independent executables (PIE) are supported" /><published>2016-03-14T00:00:00+00:00</published><updated>2016-03-14T00:00:00+00:00</updated><id>/tech/2016/03/14/Android-PIE</id><content type="html" xml:base="/tech/2016/03/14/Android-PIE.html"><![CDATA[<p>After pushing some binaries onto devices that run newer versions of Android, a frustrating error often occurs:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>error: only position independent executables (PIE) are supported.
</code></pre></div></div>

<p>The error message is quite straightforward — the binary is not position independent. If you have the source code, take a look at <a href="http://stackoverflow.com/questions/24818902/running-a-native-library-on-android-l-error-only-position-independent-executab">this stack overflow answer</a> and edit your <code class="language-plaintext highlighter-rouge">Android.mk</code> accordingly.</p>

<p>Things get more complicated if you only have the binary or it’s not feasbile to rebuild it with PIE support. Then this post can help. I stumbled across a workaround on a Chinese website. It’s very easy, even less painful than rebuilding the binary with PIE enabled.</p>

<p>Basically what you only need is a binary editor like <a href="http://www.sweetscape.com/010editor/">010 Editor</a>. Use it open the binary file, count carefully to find the 17th byte, change the value <em>02</em> to <em>03</em>, and that’s it!</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ xxd gdb | head -2
0000000: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............
0000010: 0200 2800 0100 0000 b06a 0100 3400 0000  ..(......j..4...

$ xxd gdb_pie | head -2
0000000: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............
0000010: 0300 2800 0100 0000 b06a 0100 3400 0000  ..(......j..4...
</code></pre></div></div>

<p>Save your changes and the modified binary should work well on your Android device.</p>]]></content><author><name>Yuru Shao</name></author><category term="Tech" /><category term="Android" /><category term="Troubleshooting" /><category term="Binary" /><summary type="html"><![CDATA[After pushing some binaries onto devices that run newer versions of Android, a frustrating error often occurs: error: only position independent executables (PIE) are supported.]]></summary></entry><entry><title type="html">Download Software from Dreamspark in Linux</title><link href="/tech/2015/10/05/Linux-SDM.html" rel="alternate" type="text/html" title="Download Software from Dreamspark in Linux" /><published>2015-10-05T00:00:00+00:00</published><updated>2015-10-05T00:00:00+00:00</updated><id>/tech/2015/10/05/Linux-SDM</id><content type="html" xml:base="/tech/2015/10/05/Linux-SDM.html"><![CDATA[<p>After making purchase, you’ll only be able to download a <code class="language-plaintext highlighter-rouge">.sdx</code> file. This file can be opened by SDM (Secure Download Manager), which is not available in Linux. Fortunately, we have an alternative: <a href="https://github.com/RadekSimkanic/Linux-SDM-Downloader">Linux SDM Downloader</a>. Clone Linux SDM Downloader’s source code, enter its folder, and run:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ python main.py ms-software.sdx
</code></pre></div></div>

<p>You’ll get a <code class="language-plaintext highlighter-rouge">.sdc</code> file and a <code class="language-plaintext highlighter-rouge">.sdc.key</code> file. Next you need another tool to decrypt the sdc file together with the key: <a href="https://github.com/v3l0c1r4pt0r/xSDM">xSDM</a></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ xsdm ms-software.sdc
</code></pre></div></div>

<p>Make sure that your sdc and sdc.key are located in the same folder.</p>]]></content><author><name>Yuru Shao</name></author><category term="Tech" /><category term="Linux" /><summary type="html"><![CDATA[After making purchase, you’ll only be able to download a .sdx file. This file can be opened by SDM (Secure Download Manager), which is not available in Linux. Fortunately, we have an alternative: Linux SDM Downloader. Clone Linux SDM Downloader’s source code, enter its folder, and run:]]></summary></entry><entry><title type="html">New Features of Debian Apport</title><link href="/tech/2015/07/03/Debian-Apport-GSoC.html" rel="alternate" type="text/html" title="New Features of Debian Apport" /><published>2015-07-03T00:00:00+00:00</published><updated>2015-07-03T00:00:00+00:00</updated><id>/tech/2015/07/03/Debian-Apport-GSoC</id><content type="html" xml:base="/tech/2015/07/03/Debian-Apport-GSoC.html"><![CDATA[<p>Apport intercepts program crashes, collects debugging information about the crash and runtime, and sends it to bug trackers. It also offers the user to report a bug about a package, with again collecting as much information about it as possible.</p>

<p>I’m working on the improvement of Apport in Debian this summer. So far, a few new features has been implemented.</p>

<ol>
  <li>Ensure only one instance of <code class="language-plaintext highlighter-rouge">apport-notifyd</code> is running</li>
  <li>Invoke <code class="language-plaintext highlighter-rouge">apport-retrace</code> to install absent debug symbols</li>
  <li>Leverage system cache to save bandwith</li>
  <li>Integrate Apport with Debian BTS</li>
</ol>

<h1 id="1-one-apport-notifyd-instance">1. One apport-notifyd Instance</h1>

<p>Previously, <code class="language-plaintext highlighter-rouge">apport-notifyd</code> notification daemon does not have the ability to shutdown by itself. Thus if the user logs out of his desktop session and then logs back in, he will have more than one instances of the daemon. This will result in multiple apport popups when a crash occurs.</p>

<p>Now <code class="language-plaintext highlighter-rouge">apport-notifyd</code> can detect if there has already been a notification daemon running. If not it will start a new one, otherwise it quits silently.</p>

<h1 id="2-install-debug-symbols">2. Install Debug Symbols</h1>

<p>Sometimes Apport fails to report a crash due to the lack of debugging symbols in the crashed package or its dependencies. When this happens, Apport will prompt a message dialog, telling the user to install absent debug symbols. We added an <em>install</em> button in the dialog, which can let the user install debug symbols immediately, without starting <code class="language-plaintext highlighter-rouge">apport-retrace</code> manually.</p>

<p><img src="/assets/images/20150703_install_debug_symbols.png" alt="" /></p>

<p>-&gt; Fig 1. Click “Install” to install debug symbols &lt;-</p>

<h1 id="3-leverage-system-cache">3. Leverage System Cache</h1>

<p><code class="language-plaintext highlighter-rouge">apport-retrace</code> downloads/installs the necessary packages and debug symbols. It used to download all required packages direclty from Debian servers.</p>

<p>The cache folder <code class="language-plaintext highlighter-rouge">/var/cache/apt</code> contains debian packages downloaded by <code class="language-plaintext highlighter-rouge">apt-get</code>. It’s very likely that packages <code class="language-plaintext highlighter-rouge">apport-retrace</code> wants to download have existed in <code class="language-plaintext highlighter-rouge">/var/cache/apt</code>. For such packages we don’t need to download them again – just make copies. This will save bandwith and shorten the waiting time.</p>

<h1 id="4-integrate-debian-bts">4. Integrate Debian BTS</h1>

<p>Debian has a bug tracking system (BTS) in which we file details of bugs reported by users and developers. Each bug is given a number, and is kept on file until it is marked as having been dealt with.</p>

<p>We’ve integrated Debian BTS into Apport. Before reporting a bug of the crashed package users can browse existing bug reports fetched from Debian BTS. They don’t need to report it again if the bug has alreadly been reported by someone else!</p>

<p><img src="/assets/images/20150703_apport_main.png" alt="" /></p>

<p>-&gt; Fig 2. Click “Existing Reports” to view reported bugs &lt;-</p>

<p><img src="/assets/images/20150703_existing_reports.png" alt="" /></p>

<p>-&gt; Fig 3. All existing bug reports &lt;-</p>

<p><img src="/assets/images/20150703_report_details.png" /></p>

<p>-&gt; Fig 4. Display details of one bug report &lt;-</p>]]></content><author><name>Yuru Shao</name></author><category term="Tech" /><category term="Linux" /><category term="Debian" /><category term="GSoC" /><summary type="html"><![CDATA[Apport intercepts program crashes, collects debugging information about the crash and runtime, and sends it to bug trackers. It also offers the user to report a bug about a package, with again collecting as much information about it as possible.]]></summary></entry><entry><title type="html">Debian Font Configuration Warning</title><link href="/tech/2015/04/01/Debian-Fontconfig-Warning.html" rel="alternate" type="text/html" title="Debian Font Configuration Warning" /><published>2015-04-01T00:00:00+00:00</published><updated>2015-04-01T00:00:00+00:00</updated><id>/tech/2015/04/01/Debian-Fontconfig-Warning</id><content type="html" xml:base="/tech/2015/04/01/Debian-Fontconfig-Warning.html"><![CDATA[<p>I’ve been learning to develop GUI applications for Debian with PyQt4 these days. When I ran the program in shell, two annoying warnings showed up.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Fontconfig warning: "/etc/fonts/conf.d/65-droid-sans-fonts.conf", line 103: Having multiple values in &lt;test&gt; isn't supported and may not work as expected
Fontconfig warning: "/etc/fonts/conf.d/65-droid-sans-fonts.conf", line 138: Having multiple values in &lt;test&gt; isn't supported and may not work as expected
</code></pre></div></div>

<p>As the warning messages hinted, to get rid of them I should convert multiple values in one <code class="language-plaintext highlighter-rouge">&lt;test&gt;</code> into multiple <code class="language-plaintext highlighter-rouge">&lt;test&gt;</code> tags, each of which only has one value. So I edited the file <code class="language-plaintext highlighter-rouge">/etc/fonts/conf.d/65-droid-sans-fonts.conf</code>.</p>

<h1 id="before">Before</h1>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;test name="lang"&gt;
    &lt;string&gt;zh-cn&lt;/string&gt;
    &lt;string&gt;zh-sg&lt;/string&gt;
    &lt;string&gt;zh-hk&lt;/string&gt;
    &lt;string&gt;zh-tw&lt;/string&gt;
&lt;/test&gt;
</code></pre></div></div>

<h1 id="after">After</h1>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;test name="lang"&gt;
    &lt;string&gt;zh-cn&lt;/string&gt;
&lt;/test&gt;
&lt;test name="lang"&gt;
    &lt;string&gt;zh-sg&lt;/string&gt;
&lt;/test&gt;
&lt;test name="lang"&gt;
    &lt;string&gt;zh-hk&lt;/string&gt;
&lt;/test&gt;
&lt;test name="lang"&gt;
    &lt;string&gt;zh-tw&lt;/string&gt;
&lt;/test&gt;
</code></pre></div></div>]]></content><author><name>Yuru Shao</name></author><category term="Tech" /><category term="Linux" /><category term="Debian" /><category term="Troubleshooting" /><summary type="html"><![CDATA[I’ve been learning to develop GUI applications for Debian with PyQt4 these days. When I ran the program in shell, two annoying warnings showed up.]]></summary></entry><entry><title type="html">Installing an SSD for Macbook Pro (Mid 2012 version)</title><link href="/life/2014/01/03/macbook-ssd.html" rel="alternate" type="text/html" title="Installing an SSD for Macbook Pro (Mid 2012 version)" /><published>2014-01-03T00:00:00+00:00</published><updated>2014-01-03T00:00:00+00:00</updated><id>/life/2014/01/03/macbook-ssd</id><content type="html" xml:base="/life/2014/01/03/macbook-ssd.html"><![CDATA[<p>最近从美国亚马逊海淘了一块SSD，Crucial M500 240G。加上运费共1250HKD，相比香港的价格（1400HKD左右）还是非常划算的。今天安装到了Macbook Pro （Mid 2012 13英寸）上，并完成了系统的迁移。</p>

<p>考虑到240G的容量有限，可能不够日常使用，所以需要保留原来500G的机械硬盘：系统和应用程序安装到SSD上，而home目录的一些数据，比如影音、下载的文件使用HDD存储。在淘宝上买了一个光驱位的硬盘架，这样就可以两块硬盘共存了。光驱和硬盘采用的都是SATA接口，读写速度上不会有区别，所以将SSD或者HDD安装到光驱位都可以（我直接将SSD放入硬盘架装到了光驱位）。</p>

<p>拆卸光驱比较麻烦，需要参考网上的拆机教程。SSD安装成功后重新启动系统，使用Disk Utility进行格式化，然后系统就会自动挂载它为第二块硬盘了。</p>

<p>下一步进行系统迁移：把系统从原来的HDD上克隆到SSD上，然后更改启动盘为SSD。</p>

<h3 id="1-克隆系统">1. 克隆系统</h3>

<p>使用了Carbon Copy Cloner这个app，操作起来非常方便。</p>

<p><img src="/assets/images/ccc.png" alt="" /></p>

<p>左边选择HDD和需要克隆的目录，右边选择目标SSD。因为HDD中的数据量大于SSD的容量，所以对于home目录<code class="language-plaintext highlighter-rouge">/Users/username/</code>，仅同步其中的用户配置文件就可以了。克隆过程并不慢，我用了大约一小时。</p>

<h3 id="2-设置默认启动盘">2. 设置默认启动盘</h3>

<p>接下来，在System Preference - Startup Disk中选择默认启动盘为SSD，重启会发现系统的启动速度变快了。</p>

<p>最后，可以将HDD中的系统删掉，仅用它来存储数据。关于SSD的优化可以参考：<a href="http://blog.jjgod.org/2010/04/17/macosx-ssd-tweaks/">http://blog.jjgod.org/2010/04/17/macosx-ssd-tweaks/</a></p>]]></content><author><name>Yuru Shao</name></author><category term="Life" /><category term="Macbook" /><category term="SSD" /><summary type="html"><![CDATA[最近从美国亚马逊海淘了一块SSD，Crucial M500 240G。加上运费共1250HKD，相比香港的价格（1400HKD左右）还是非常划算的。今天安装到了Macbook Pro （Mid 2012 13英寸）上，并完成了系统的迁移。]]></summary></entry><entry><title type="html">Collaboration vs Cooperation</title><link href="/2013/12/23/collaboration-vs-cooperation.html" rel="alternate" type="text/html" title="Collaboration vs Cooperation" /><published>2013-12-23T00:00:00+00:00</published><updated>2013-12-23T00:00:00+00:00</updated><id>/2013/12/23/collaboration-vs-cooperation</id><content type="html" xml:base="/2013/12/23/collaboration-vs-cooperation.html"><![CDATA[<p>这两个词都是“合作”的意思，有时候也可以互换使用。但是它们代表着两种根本不同的对group做出贡献的方式。</p>

<blockquote>
  <p>When collaborating, people work together (co-labor) on a single shared goal. When cooperating, people perform together (co-operate) while working on selfish yet common goals.</p>
</blockquote>

<p>collaborate表示大家一起为同一个目标努力。而cooperate表示大家在一起为各自的目标努力，但可能有相似的目标。</p>

<p><br /></p>

<h3 id="参考资料">参考资料</h3>

<ol>
  <li><a href="http://cloudhead.headmine.net/post/3279118157/cooperation-vs-collaboration">http://cloudhead.headmine.net/post/3279118157/cooperation-vs-collaboration</a></li>
</ol>]]></content><author><name>Yuru Shao</name></author><category term="" /><category term="" /><summary type="html"><![CDATA[这两个词都是“合作”的意思，有时候也可以互换使用。但是它们代表着两种根本不同的对group做出贡献的方式。]]></summary></entry></feed>