tag:blogger.com,1999:blog-47835120646343088012024-03-14T12:06:57.088+08:00安追碎碎唸程式 ▪ 旅行 ▪ 思考 ▪ 動手Unknownnoreply@blogger.comBlogger68125tag:blogger.com,1999:blog-4783512064634308801.post-1625968939519249892022-10-13T15:42:00.009+08:002023-07-01T09:56:32.521+08:00Swimlane Beta User Interview with ClickUp<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiV2j6hb0atE1D4c8UQgfAsHYTJnZ-7dqljoWJtU_UqAr6l2apd-OnyQXl2qMTurY-AktjkPShBuxfNl-AjhG0Q-paAJXPD1T4Du64xSw4_ttHVvCwaHCMvGchORrqFiVk4B8MYuWikTsWI_6LOEw5dIDPj_HhpQy2LRin64wO4HTNKXfqcrxKQylWAA/s1286/Screen%20Shot%202022-10-13%20at%203.37.19%20PM.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="695" data-original-width="1286" height="346" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiV2j6hb0atE1D4c8UQgfAsHYTJnZ-7dqljoWJtU_UqAr6l2apd-OnyQXl2qMTurY-AktjkPShBuxfNl-AjhG0Q-paAJXPD1T4Du64xSw4_ttHVvCwaHCMvGchORrqFiVk4B8MYuWikTsWI_6LOEw5dIDPj_HhpQy2LRin64wO4HTNKXfqcrxKQylWAA/w640-h346/Screen%20Shot%202022-10-13%20at%203.37.19%20PM.png" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Credit: <a href="http://clickup.com">clickup.com</a></td></tr></tbody></table><p>Yesterday (2022/10/12), I had <a href="https://clickup.canny.io/feature-requests/p/swimlanes-beta-feedback" target="_blank">a beta user interview</a> with ClickUp. It was a great experience. Their PM asked me many questions about our scenarios and we talked a lot. The most important thing is that I knew they will fix some major issues finally. Frankly, I am almost going to give up ClickUp and switch back to Jira Cloud. I even left a reply on <a href="https://clickup.canny.io/feature-requests/p/swimlanes-on-board-view" target="_blank">Canny</a> before they announced the beta:</p><div style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3X9l6PXYMASpVlgwb1GQZOjohsoQbfNe82UDyKmsX2v2msuAkq5c4dIhq3UNiUiBV39uhLVkA4Jvqb_kEbXj04-351TZVjZpockFF_tv4WdHfiSrg6flXQsguiNM6Dvhc16Ux0t1Q_DVOEh9wSMVldVEusmDSO6HjJlJnw0To5GUWdDf4wPiPZi5qfQ/s629/Screen%20Shot%202022-10-15%20at%2011.22.31%20AM.png"><img border="0" data-original-height="247" data-original-width="629" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3X9l6PXYMASpVlgwb1GQZOjohsoQbfNe82UDyKmsX2v2msuAkq5c4dIhq3UNiUiBV39uhLVkA4Jvqb_kEbXj04-351TZVjZpockFF_tv4WdHfiSrg6flXQsguiNM6Dvhc16Ux0t1Q_DVOEh9wSMVldVEusmDSO6HjJlJnw0To5GUWdDf4wPiPZi5qfQ/s16000/Screen%20Shot%202022-10-15%20at%2011.22.31%20AM.png" /></a></div><p>Let me do the recap and intro.</p><p>What is ClickUp? It is an all-in-one SaaS management tool but we only use it as our task management tool for our Scrum.</p><p>We were used to use Jira for tracking our tickets. But back to the beginning of this year, we have some new Web3 products and some of our teammates were tired of the lagging of Jira Cloud. So, they proposed to use ClickUp and I agreed with them to use it as PoC for new products during that time.</p><p>But soon, I noticed that ClickUp has some major weak points to do the management compares to Jira. Although they developed the beta version of swimlane after almost 4 years of the <a href="https://clickup.canny.io/feature-requests/p/swimlanes-on-board-view" target="_blank">first proposal</a>, they still need much time to improve them.</p><p>Hence, if you want to run Scrum, Jira might still be your first choice at this moment. (Even though Jira Cloud is really quite slow.) But don't get me wrong, I truly hope that ClickUp can accelerate their development speed and fix the pain points of management views then competing with Jira.</p><p>I listed the major weak points as below and you can make them as your checkpoints if the team figure them out,</p><p></p><ul style="text-align: left;"><li>No swimlanes and No "Group by User Story". </li><li>Forced users to focus one task at a time.</li><li>They separate their calendar by each month.</li></ul><div><br /></div><div>More about the issues:</div><h4 style="text-align: left;">No swimlanes and No "Group by User Story"</h4><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1-d60pzTt3gvnXQGBbElMibvinq7ICLiA7zhuWiHjbbGTUx8c2Wer_Qq5O2mzlvpXVPAdKWeO36ZjSjUIPsO4698F7KTyhitJpa6FJ2j0swhbTYPl93ykNkxbuQccNwUXbRwl8kWp1XHqlrY8utcu3WMzHnQKHLwyKkpd5Wfkr8vAdnj8kAqibAt6Tg/s1693/Xnip2022-10-13_14-44-56.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="735" data-original-width="1693" height="278" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1-d60pzTt3gvnXQGBbElMibvinq7ICLiA7zhuWiHjbbGTUx8c2Wer_Qq5O2mzlvpXVPAdKWeO36ZjSjUIPsO4698F7KTyhitJpa6FJ2j0swhbTYPl93ykNkxbuQccNwUXbRwl8kWp1XHqlrY8utcu3WMzHnQKHLwyKkpd5Wfkr8vAdnj8kAqibAt6Tg/w640-h278/Xnip2022-10-13_14-44-56.png" width="640" /></a></div><br /><div>Without swimlanes and "Group by User Story" will make you feel helpless and the board is <b><i><span style="color: red;">useless</span></i></b> when you are in your "standup (or sync) meeting". If ClickUp has swimlanes and the tickets can be grouped by user story, it will be very easy to acknowledge the current status of the user stories. You only have to focus on the swimlanes to make sure the user stories have been DONE or ACCEPTED.</div><div><br /></div><h4 style="text-align: left;">Forced users to focus one task at a time</h4><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg99frmuhY4jvKkHwsjdYf0nVDODeltp13NspWTqUZTaDKGDVoD023FNvjTvPlHNQ-5c5hRZVEo-xtO6H74XrH9vuzS5-vMagGjy-EH5mk2scRZ0GfFIn8jEzPTTmOdlNPYsp9gBmNpNL-rwCOpX7JHhQn0HOY7Jvwguz9n5jpOONasgpQ28LPZNGWmoA/s1877/Xnip2022-10-13_15-11-32.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1281" data-original-width="1877" height="436" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg99frmuhY4jvKkHwsjdYf0nVDODeltp13NspWTqUZTaDKGDVoD023FNvjTvPlHNQ-5c5hRZVEo-xtO6H74XrH9vuzS5-vMagGjy-EH5mk2scRZ0GfFIn8jEzPTTmOdlNPYsp9gBmNpNL-rwCOpX7JHhQn0HOY7Jvwguz9n5jpOONasgpQ28LPZNGWmoA/w640-h436/Xnip2022-10-13_15-11-32.png" width="640" /></a></div><br /><div>When you want to see the details of one specific task, ClickUp will open a giant window and make you focus on this task. Then you can not switch to another ticket or take a glance at them at the same time. It's not a good design for a manager but a developer (executor).</div><div><br /></div><h4 style="text-align: left;">They separate their calendar by each month</h4><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8qV89edptmBAYG8SR6wsX2b8Y-fZ9EnQYcLwzhCFaMFPyflKxrboEV6zSBP18e5PFd0RaooBnAwDwxEXX7iTjgS0LylyZeV_RcIBmywH_Vp0G58wuBApRXg9K-5V7aeYJXom8nlSeGilUG8sDrstNg7ny2dis-xM6p5LRIds68AgdD7Ksx9bwUJ9aDg/s2255/Xnip2022-10-13_15-20-29.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1246" data-original-width="2255" height="354" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8qV89edptmBAYG8SR6wsX2b8Y-fZ9EnQYcLwzhCFaMFPyflKxrboEV6zSBP18e5PFd0RaooBnAwDwxEXX7iTjgS0LylyZeV_RcIBmywH_Vp0G58wuBApRXg9K-5V7aeYJXom8nlSeGilUG8sDrstNg7ny2dis-xM6p5LRIds68AgdD7Ksx9bwUJ9aDg/w640-h354/Xnip2022-10-13_15-20-29.png" width="640" /></a></div><br /><div>We won't separate our project plans or milestones by month, the calendar view shouldn't do that as well. They should allow users to scroll the calendar but not using the option switcher.</div><div><br /></div><h4 style="text-align: left;">Updates</h4><div>Although Jira has a higher learning curve and requires more effort to operate, the high flexibility of JQL combined with the comprehensiveness of its automation processes make it difficult to leave the comfort zone made by Jira. This is especially true considering the recent improvements they have made (as of 2023/04/09) which have significantly increased its speed.</div><div><br /></div><p></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-19804783682977179802022-10-05T16:02:00.002+08:002022-10-13T15:58:50.086+08:00Save your legacy Jenkins when upgrading<p> </p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4MqcXjyVX3wHixTTAar4Fxxp6H6faJ0hcm2aAKQYp9JCU9YQkm7I4GvJMjtBsllbn1nmAxrIM4Td_EtrFbXsGNmupMD3RHzieUOaNJoe4yLRXzaOXP-703mtfda2IKydJ3jagheVUHHOi69OMsMJO9NX_Zx5fMXwN0DHnYEUJLS2joC20Qf7V4nmNKQ/s256/256.png" style="margin-left: auto; margin-right: auto;"><img alt="Jenkinstein" border="0" data-original-height="256" data-original-width="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4MqcXjyVX3wHixTTAar4Fxxp6H6faJ0hcm2aAKQYp9JCU9YQkm7I4GvJMjtBsllbn1nmAxrIM4Td_EtrFbXsGNmupMD3RHzieUOaNJoe4yLRXzaOXP-703mtfda2IKydJ3jagheVUHHOi69OMsMJO9NX_Zx5fMXwN0DHnYEUJLS2joC20Qf7V4nmNKQ/s16000/256.png" title="Credit by https://www.jenkins.io/artwork/" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Image by <a href="https://www.jenkins.io/artwork/">https://www.jenkins.io/artwork/</a></td></tr></tbody></table><div><br /></div><div>Recently, I've been working on helping the team refactor the old legacy Jenkins and smoother the CI/CD flows. It's been almost 2 years since its last upgrade. It's terrifying but we have to fix it.</div><div><br /></div><div>I left some notes and tips here if someday I need this remarkable memory. (It's been a long time since I last fixed the Jenkins.)</div><div><br /></div><div>To save your Jenkins, you <b>MUST</b> follow the steps as following. Otherwise, you need a big heart and having the attitude that are not afraid of being shocked if all jobs are gone. (Not only the Jenkins Jobs but also ...)</div><div><br /></div><div>TL; DR</div><div><ol style="text-align: left;"><li>Note the <b>origin</b> Jenkins version. For example, <b>2.263.1</b></li><li>Find and note the WAR file path. For example, <b>/usr/share/jenkins/jenkins.war</b></li><li>The Jenkins home path. For example, <b>/var/jenkins_home</b></li><li>Copy the whole Jenkins home directory to another directory. For example, <b>/opt/jenkins_home2</b> </li><li>(Optional) Double check that you have another backup plugin like <b>ThinBackup</b> and where are those data?</li></ol></div><div>If you finished at least step 1 to 4, then you are free to go to upgrade anything you like. Click and upgrade the missing patches you have been warned.</div><div><br /></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-Xc-TqNRCdqd7gDIqBK0xxnUqp35Z0-RYqVqd8GmGwVfl0wjUh1e6TaDQVm9xkxt6eVeOHixsBDFzx_2mCwUetYSsMSw3puIvfGotFvEMBBXnVYSiCGCHBSrodMiG9x6AO9uwGir3Cs8igKKR2SZukgAE58xcZAafXosRTk9lxR1hOLPsZ68A9zpFSg/s1389/Screen%20Shot%202022-10-05%20at%2010.39.26%20AM.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="631" data-original-width="1389" height="290" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-Xc-TqNRCdqd7gDIqBK0xxnUqp35Z0-RYqVqd8GmGwVfl0wjUh1e6TaDQVm9xkxt6eVeOHixsBDFzx_2mCwUetYSsMSw3puIvfGotFvEMBBXnVYSiCGCHBSrodMiG9x6AO9uwGir3Cs8igKKR2SZukgAE58xcZAafXosRTk9lxR1hOLPsZ68A9zpFSg/w640-h290/Screen%20Shot%202022-10-05%20at%2010.39.26%20AM.png" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Warnings and Suggestions</td></tr></tbody></table><br /><div>And then, if you are the one who is in the same situation like the team. There are 80% or more possibility the legacy Jenkins will not be running anymore. Especially you have as more as plugins on your Jenkins.</div><div><br /></div><div>There will be thousands of tons of dependancies you need to fix. Sometimes, some plugins are deprecated and you have no new versions to fix the issues. So, you need to remove them and find the replacements. It will be long journey and it's hard to finish without pains.</div><div><br /></div><div>The common case you will get is: <b><i>after upgrading, unfortunately, your Jenkins is no longer working anymore</i></b>.</div><div><br /></div><div>But we still can try recovering it by the following steps, </div><div><br /></div><div>NOTE: The example is using Docker but same concept if you didn't install your Jenkins on it.</div><div><ol style="text-align: left;"><li>Go to <a href="https://get.jenkins.io/war/" target="_blank">Jenkins' official website</a> and download the origin version. For example, 2.263.1.</li><li>Mount/replace the war to the new one. For example: <b>docker run -d -it -v /opt/jenkins.war.2.263.1:/usr/share/jenkins/jenkins.war</b></li><li>Mount/replace the Jenkins home with the old one. For example: <b>docker run -d -it -v /opt/jenkins_home2:/var/jenkins_home</b></li><li>Run it again.</li></ol></div><div>If you are lucky enough, your Jenkins should be back to normal (but the legacy one) again.</div><div><br /></div><div>Congrats!</div><div><br /></div><div><br /></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-37306578353337362132022-09-05T17:13:00.002+08:002022-10-13T15:59:40.008+08:00How we did to reduce 95% bundle (docker, container) size of a Nuxt 3 (rc8) app<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKmHlkgZQgVR4Y_A-tpYHn8OUlVMngo5eP2KKQUuJGK3d9GLCH517NjdF48y6snVr7WQ7v-jOTYgn-pmETJHNkyfrgvmMBggjijHwjFWpuvQjzIad_QMP9y-R6n9gk2f9xiBDnD0im2DPyuseot2MG6PUqX46enYr_f1llkeuWRca-IKU1EvwMzPm7FA/s656/Screen%20Shot%202022-09-07%20at%201.46.04%20PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="391" data-original-width="656" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKmHlkgZQgVR4Y_A-tpYHn8OUlVMngo5eP2KKQUuJGK3d9GLCH517NjdF48y6snVr7WQ7v-jOTYgn-pmETJHNkyfrgvmMBggjijHwjFWpuvQjzIad_QMP9y-R6n9gk2f9xiBDnD0im2DPyuseot2MG6PUqX46enYr_f1llkeuWRca-IKU1EvwMzPm7FA/s16000/Screen%20Shot%202022-09-07%20at%201.46.04%20PM.png" /></a></div><br /><p>To be honest, I am a newbie to <a href="https://github.com/nuxt/framework" target="_blank">Nuxt 3</a>, so, any comments are welcome.</p><p>Last week (2022/08/30), I noticed that my members are using Nuxt 3 and the bundle size was tremendous. Therefore, I want to reduce the size by using the multi-stage method and using <b><u>node:alpine</u></b>. </p><p><b><u>Spoiler:</u></b> You can check out the result below by size before (2.88GB) and after (131MB).</p><pre class="prettyprint linenums"><code class="lang-shell">REPOSITORY TAG IMAGE ID CREATED SIZE
myapp v1.0.2 5ffd6627a861 12 seconds ago 131MB
myapp v1.0.1 ef13e87402c4 20 hours ago 2.88GB</code></pre><div><br /></div>Once you started your app with Nuxt 3, now you can use the Dockerfile below and put it in the project's root directory (or any path you like) to build your docker image.<div><br /></div><div><b><span style="color: red;">WARN</span></b>: You need to make sure that your app is compatible with <b><u>node:alpine</u></b>.</div><div><div> <div>The <b><i>Dockerfile</i></b>:
<pre class="prettyprint linenums"><code class="lang-shell">FROM node:16.17.0 AS base
#### multi-stage: builder
FROM base AS builder
RUN mkdir -p /src
COPY . /src
WORKDIR /src
# config/.env should be mounted or replace with config/.env.example
RUN ["cp", "/src/config/.env.example", "/src/config/.env"]
RUN yarn install
RUN yarn build
#### multi-stage: runner
FROM node:16.17.0-alpine3.16
WORKDIR /app
COPY --from=builder /src/.output /app/.output
COPY --from=builder /src/nuxt.config.ts /app/
COPY --from=builder /src/public /app/
COPY --from=builder /src/config /app/
COPY --from=builder /src/.env /app/
EXPOSE 3000
CMD source .env ; node /app/.output/server/index.mjs
</code></pre></div></div></div><div><br /></div>
NOTE1: I also did some tricks for runtimeConfig in the file, if you don't need it, remove it and revise it to your version.<div><br /></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-63026744941444652722020-07-08T14:33:00.018+08:002020-07-08T20:32:42.449+08:00Kubernetes (GKE) 裡 TCP Socket 連線取得正確來源(玩家) IP<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-tzm2tEVjtdU/XwWsc9vp4vI/AAAAAAABCBw/OXVL4NuIF4AtC3tFReDdmgC9GM7eE2oLACK4BGAsYHg/s670/Screen%2BShot%2B2020-07-08%2Bat%2B3.45.53%2BPM.png" style="margin-left: auto; margin-right: auto;"><img alt="Wrong Source IPs" border="0" data-original-height="292" data-original-width="670" src="https://1.bp.blogspot.com/-tzm2tEVjtdU/XwWsc9vp4vI/AAAAAAABCBw/OXVL4NuIF4AtC3tFReDdmgC9GM7eE2oLACK4BGAsYHg/d/Screen%2BShot%2B2020-07-08%2Bat%2B3.45.53%2BPM.png" title="來源 IP 都是內部 IP" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">來源 IP 都是內部 IP</td></tr></tbody></table><div>這次的案例是之前曾經幫忙過的一個案子
, 一個原本是在虛擬主機上運行, 最後進行容器化並且轉到 Kubernates 上營運的遊戲產品, 這案子大都是使用 GCP 的解決方案來處理。</div><div><br /></div><div>在這案例遇到的問題是:<span style="background-color: #f4c7c3;"> 在稽核玩家資訊時發現, 後台紀錄的玩家來源 IP 都是 Cluster 中 Node 的 IP</span>, 所以需要儘速進行修正。<br /><br />值得一提的是這個遊戲在玩家和伺服器間是使用 TCP Socket 連線, 所以有些和 HTTP Header X-Forwarded-For 相關的解決方案就可能不是那麼適用了, proxy protocol 也有可能是另一種解法, 只是這次的解法是從 K8S 直接有提供的方式來處理。</div><div><br /></div><div>大概簡單介紹一下系統的架構實作:這個遊戲產品採用的是 Master version 為 1.16.9-gke.6 的 GKE 服務 (一組在 GCP 上的 Kubernetes Cluster)。 發生問題的服務是由 Service type 為 <span style="background-color: #fce8b2;">Load balancer</span> 在最前線, 接著 request 會被導向相關的 Pod 裡, 具體細節可以從下面的 spec 看出來。</div><div><br /></div><div>以下為隱碼過的部分示意 YAML 檔:<br /><pre class="prettyprint linenums"><code class="lang-yaml">spec:
clusterIP: xx.xx.xx.xx
healthCheckNodePort: xxxx
ports:
- name: xxxService
nodePort: xxxxx
port: xxxx
protocol: TCP
targetPort: xxxx
selector:
app: xxx
release: xxxcluster
sessionAffinity: None
type: LoadBalancer</code>
</pre>
遊戲是使用 <span style="background-color: #fce8b2;">Apache MINA</span> 來開發, 取得來源 IP 的程式碼和網路上的範例類似:
<pre class="prettyprint linenums"><code class="lang-java">String clientIP = ((InetSocketAddress)session.getRemoteAddress()).getAddress().getHostAddress();</code></pre>Google 後有很多解法, 但大都不是我要的解法。最後還是得乖乖回去查 <a href="https://kubernetes.io/zh/docs/tutorials/services/source-ip/" target="_blank">Kubernetes 官方文件</a>, 文件內有一個地方引起我的注意, 看了一下後覺得應該可以解決這次發生的問題, 文件裡面提到 externalTrafficPolicy 的說明:</div><div><span style="background-color: white; color: #222222; font-size: 16px;"></span><blockquote><span style="background-color: white; color: #222222; font-size: 16px;">Kubernetes has a feature to </span><a href="https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip" style="background-color: white; box-sizing: border-box; color: #184eb1; font-size: 16px; text-decoration-line: none;">preserve the client source IP</a><span style="background-color: white; color: #222222; font-size: 16px;">. If you set </span><code style="background-color: rgba(0, 0, 0, 0.05); border-radius: 0.25rem; box-sizing: border-box; color: #222222; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; word-break: normal;">service.spec.externalTrafficPolicy</code><span style="background-color: white; color: #222222; font-size: 16px;"> to the value </span><code style="background-color: rgba(0, 0, 0, 0.05); border-radius: 0.25rem; box-sizing: border-box; color: #222222; font-size: 13.6px; margin: 0px; padding: 0.2em 0.4em; word-break: normal;">Local</code><span style="background-color: white; color: #222222; font-size: 16px;">, kube-proxy only proxies proxy requests to local endpoints, and does not forward traffic to other nodes. This approach preserves the original source IP address. If there are no local endpoints, packets sent to the node are dropped, so you can rely on the correct source-ip in any packet processing rules you might apply a packet that make it through to the endpoint.</span></blockquote><span style="background-color: white; color: #222222; font-size: 16px;"></span></div><div>只要把 externalTrafficPolicy: Local 加進去 Service 的 YAML 檔裡就可以了:<br /><pre class="prettyprint linenums"><code class="lang-yaml">spec:
clusterIP: xx.xx.xx.xx
healthCheckNodePort: xxxx
externalTrafficPolicy: Local
ports:
- name: xxxService
nodePort: xxxxx
port: xxxx
protocol: TCP
targetPort: xxxx
selector:
app: xxx
release: xxxcluster
sessionAffinity: None
type: LoadBalancer</code>
</pre><div><br /></div><div>加完更新後也的確順利地讓這個案件結案。</div><div><br /></div><div><br /></div><div><br /></div>註:具體處理還是得看架構和服務, 請先了解這個設定和原理, 確認是不是你所需要的再進行改動, 擅自更動可能會造成 Service 無法正常啟動。</div><div><br /></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-20504027772897138482019-12-20T14:44:00.001+08:002020-03-11T20:01:50.551+08:00Building cross-site (CORS) Socket.IO/WebSocket in Go on GKE, Google Cloud Platform (GCP)<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-jIa3RHYjvT8/XfxtbfXL2hI/AAAAAAAA9lc/NHWcz8n0JjADyzF-TJLYg4RYj1KknOLNgCLcBGAsYHQ/s1600/Screen%2BShot%2B2019-12-20%2Bat%2B2.34.52%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="284" data-original-width="848" height="214" src="https://1.bp.blogspot.com/-jIa3RHYjvT8/XfxtbfXL2hI/AAAAAAAA9lc/NHWcz8n0JjADyzF-TJLYg4RYj1KknOLNgCLcBGAsYHQ/s640/Screen%2BShot%2B2019-12-20%2Bat%2B2.34.52%2BPM.png" width="640" /></a></div>
If you are going to build your own Socket.IO server to keep the connections between your clients and servers via WebSocket in Golang instead of NodeJS. Here are our stories that may save your time and energy.<br />
<br />
At the very beginning, you will get two packages after you did quick searches on Google, those are <b style="background-color: #fff2cc;">github.com/gorilla/websocket</b> and <b style="background-color: #fff2cc;">github.com/googollee/go-socket.io</b>. One is for WebSocket and the other is for Socket.IO.<br />
<br />
Since Socket.IO has been a while in our tech stack and we believe that Socket.IO will help us avoid the legacy protocol and some connection routine issues. We decided to use Socket.IO as our solution for the coming project due to the rush schedule, we didn't spend much time on this topic.<br />
<br />
For Socket.IO in Go, it's very easy to make a workable example for both client and server sides by following the <i>README</i> of <a href="http://github.com/googollee/go-socket.io">github.com/googollee/go-socket.io</a>. And after thinking about the design for connection management (Using queue and pubsub pattern), you will jump to conclusions easily and think the POC (Proof of Concept) is done.<br />
<br />
Note: We initialize the connection on client-side like this,<br />
<pre class="prettyprint linenums"><code class="lang-js">socket = io('https://a.com', {
path: '/oursocketio',
transports: ['websocket'],
});
// Only using polling when reconnect_attempt
socket.on('reconnect_attempt', () => {
socket.io.opts.transports = ['polling', 'websocket'];
});</code>
</pre>
Then the story will begin...<br />
<blockquote class="tr_bq">
WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 400</blockquote>
After googling, you may consider this error is a <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" target="_blank">CORS</a> problem. That is a common issue if you implement your Socket.IO/WebSocket server on domainA.com and you want to allow domainB.com to connect with your server. (If you use <b><i>pure WebSocket client to connect to a Socket.IO server</i></b>, you may get the similar error due to the implementation.)<br />
<br />
Then you will try adding the <i>Access-Control-Allow-Origin</i>, <i>Access-Control-Request-Method</i>, etc into your response's header on the server-side.<br />
<br />
And you won't forget the non-<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests" target="_blank">simple requests</a> and their good friend, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests" target="_blank">Preflight Requests</a>. Long story short, for some security reasons, web browsers will send an <b>OPTION</b> request before a non-simple request for cross-site resource sharing.<br />
<br />
Since we had a middleware to check all the requests for authentication and authorization, we need to do a specific modification for OPTION requests to fix the "Preflight" issue.<br />
<br />
Sometimes, the annoyed CORS issue will still be there to bother you after adding a lot of "Access-*" headers into your requests. At this moment, you can probably check this <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" target="_blank">MDN page</a> carefully. Maybe you will find out the clues like this:<br />
<blockquote class="tr_bq">
However, if the request is one that triggers a preflight due to the presence of the <b>Authorization</b> header in the request, you won’t be able to work around the limitation using the steps above. And you won’t be able to work around it at all unless you have control over the server the request is being made to.</blockquote>
If you have an <b>Authorization</b> header (For example, Bearer token.) in your HTTP requests. You should double confirm that you did not only set a wildcard (*) to Access-Control-Allow-Headers for Authorization as described below.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-hCJpqIhbUak/XfxbhjxzpoI/AAAAAAAA9lQ/ehHWm2N-qCkGB5pDk3CPyLggS_vwq1uUACLcBGAsYHQ/s1600/Screen%2BShot%2B2019-12-20%2Bat%2B1.26.04%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="606" data-original-width="1390" height="276" src="https://1.bp.blogspot.com/-hCJpqIhbUak/XfxbhjxzpoI/AAAAAAAA9lQ/ehHWm2N-qCkGB5pDk3CPyLggS_vwq1uUACLcBGAsYHQ/s640/Screen%2BShot%2B2019-12-20%2Bat%2B1.26.04%2BPM.png" width="640" /></a></div>
Note: for more details, check this <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers" target="_blank">Access-Control-Allow-Headers - HTTP | MDN</a>.<br />
<br />
The next you may get<br />
<blockquote class="tr_bq">
Error during WebSocket handshake: Unexpected response code: 403</blockquote>
When you think you finally finished the CORS issue.<br />
<br />
If you are using <b style="background-color: #fff2cc;">go-socket.io</b> <b>v1.4.2</b> or older versions. You need to override the (websocket.Default).CheckOrigin() like this for checking the origin.<br />
<pre class="prettyprint linenums"><code class="lang-go">func NewSocketServer(ctx context.Context, mux *http.ServeMux) error {
pt := polling.Default
wt := websocket.Default
wt.CheckOrigin = func(req *http.Request) bool {
// Check the origin here
// We use "return true" here for demo, NOT RECOMMENDED.
return true
}
server, err := socketio.NewServer(&engineio.Options{
Transports: []transport.Transport{
pt,
wt,
},
})
if err != nil {
return err
}
socketioSrv = server</code></pre>
<br />
Then we received many logs:<br />
<blockquote class="tr_bq">
websocket: close 1006 (abnormal closure): unexpected EOF</blockquote>
It reminded us that we need to set up a <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/configure-backend-service" target="_blank">backend config</a> for increasing the timeout. But you still need to keep in mind you can not extend the timeout due to the <a href="https://cloud.google.com/load-balancing/docs/backend-service#backend_service_settings" target="_blank">documentation</a>:<br />
<blockquote class="tr_bq">
When sending WebSocket traffic to an HTTP(S) load balancer, the backend service timeout is interpreted as the maximum amount of time that a WebSocket, idle or active, can remain open.</blockquote>
At last, you can have your own SocketIO server happily ever after. (Hopefully.)Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-48582397254949136292019-09-12T22:00:00.002+08:002022-10-25T09:55:49.948+08:00Use Kompose to convert docker-compose.yaml but got an error decoding 'Ports': No port specified: :: <empty><div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-BcNmsEEeAZ0/XXpRZh9lA-I/AAAAAAAA7r4/BJ0uUfcKALQlXgUE-X4XlveCSpBDv_MNQCLcBGAsYHQ/s1600/use-kompose-to-convert-docker-compose-yaml-but-got-an-error.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="368" data-original-width="1380" height="169" src="https://1.bp.blogspot.com/-BcNmsEEeAZ0/XXpRZh9lA-I/AAAAAAAA7r4/BJ0uUfcKALQlXgUE-X4XlveCSpBDv_MNQCLcBGAsYHQ/s640/use-kompose-to-convert-docker-compose-yaml-but-got-an-error.png" width="640" /></a></div>
<br />
Today (2019/Sep/12), I needed to convert our docker-compose.yaml to Kubernetes YAML files for saving my life. My colleague suggested me to use <a href="https://github.com/kubernetes/kompose" target="_blank">Kompose</a> (1.18.0) to do the conversions.<br />
<br />
<div>
But unfortunately, after I executed the following command,</div>
<pre class="prettyprint linenums"><code class="lang-sh">$ kompose convert -v -f docker-compose.yaml</code>
</pre>
the bad luck messages were coming out,<br />
<pre class="prettyprint linenums"><code class="lang-sh">DEBU Checking validation of provider: kubernetes
DEBU Checking validation of controller:
DEBU Docker Compose version: 3
FATA 1 error(s) decoding:
* error decoding 'Ports': No port specified: :: <empty></code>
</pre>
I noticed the problem should be related to "(Environment) Variables". Because the values of variables in <b>.env</b> file were not passed to Kompose and the error wouldn't happen when I used constants. Even though there are many PRs, like this one,<br />
<blockquote class="tr_bq">
- <a href="https://github.com/kubernetes/kompose/issues/1104" target="_blank">error decoding 'Ports': No port specified: ::<empty> #1104</a></blockquote>
or these,<br />
<blockquote class="tr_bq">
- <a href="https://github.com/docker/libcompose/pull/448" target="_blank">Fixes .env file lookup #448</a><br />
- <a href="https://github.com/kubernetes/kompose/issues/650" target="_blank">v3 env substitution is not working #650</a>
</blockquote>
Or more, they didn't fix the issue I had.<br />
<br />
To be honest, I only check 3-5 source files at that moment since I needed a quick solution for our tasks and to escape from this issue.<br />
<br />
Then, I think if I can load the .env file and output it to a temp file. That will be perfect! I googled it and here are we go: <span style="background-color: #ffe599;">docker-compose config</span> (I got this from a PR but I can't find it anymore. Sorry about it.) The concept of the command below is: the variables will be transformed to values and will be saved as a new docker-compose.yaml file,<br />
<pre class="prettyprint linenums"><code class="lang-sh">$ docker-compose config > ./k8s/docker-compose.yaml</code>
</pre>
Then, to walk into the ./k8s directory and execute the first command again,<br />
<pre class="prettyprint linenums"><code class="lang-sh">$ kompose convert -v -f docker-compose.yaml</code>
</pre>
We can live happily ever after. Done.<div><br /></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-20286130095105437452017-10-25T22:46:00.001+08:002017-11-03T10:41:40.596+08:00驚奇 2017 發生的十個第一次和我的下一步今天,人生不知不覺地又過了個年頭,看著躺在草稿匣裡好幾篇一直沒辦法結尾的文章總覺得有點心虛,因為今天這篇沒什麼營養,就只是在述說我 2017 的流水帳文章,卻後發先至地搶了個頭被發佈了。<br />
<br />
因為今年對我來說,有許許多多的人生第一次同時發生,就像摻在一起做成了撒尿牛丸的那刻一樣值得寫篇文紀念。<br />
<br />
故事得從一過了今年的一月一號開始說起,難得的元旦假期,小兒子生病初體驗就生了場大病掛急診,第一次陪著小兒子在醫院裡,幾乎要不眠不休地起床照顧他,小小的腺病毒卻讓我們有了大大的麻煩。這是第一個不想要卻得迎來的第一次。<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-qp7QFpvTADg/WexPEyMJ2SI/AAAAAAAAqbE/-Dal_XrTlRIeI9JGM_PCHH5kAIaAqOYGgCLcBGAs/s1600/20170105_063232.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="900" data-original-width="1600" height="360" src="https://1.bp.blogspot.com/-qp7QFpvTADg/WexPEyMJ2SI/AAAAAAAAqbE/-Dal_XrTlRIeI9JGM_PCHH5kAIaAqOYGgCLcBGAs/s640/20170105_063232.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">生病時候只想睡在我身上的小兒子</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-Z8slBhV-QNI/WexPy2YLvhI/AAAAAAAAqbo/3CA2C1VsKUwyPLV4fyLaw1EhTM3-eIHKwCLcBGAs/s1600/20170105_120332.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="900" data-original-width="1600" height="360" src="https://3.bp.blogspot.com/-Z8slBhV-QNI/WexPy2YLvhI/AAAAAAAAqbo/3CA2C1VsKUwyPLV4fyLaw1EhTM3-eIHKwCLcBGAs/s640/20170105_120332.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">不肯在氧氣罩裡面睡的小傢伙,我要努力幫他換姿勢跟位置</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
就在我自以為每年給同一位親戚的人情保單大約在新台幣二十萬元的左右,兒子生病應該基本住院都有涵蓋的情況下,那份高度信任得到的回報卻是他們自己高度的佣金:他們幫我家那隻出生五個月的小兒子買了所謂的終身殘扶險。令人不禁莞爾的是,這份終身殘扶險到未來真的發生狀況時,可能連請個看護都不夠。<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://4.bp.blogspot.com/-ePDyDM3FPsw/WexQlRcNRPI/AAAAAAAAqb0/9l7gxh03-GkWxs_IKCKcBDxeDvzNpYBSgCLcBGAs/s1600/Screen%2BShot%2B2017-10-22%2Bat%2B3.01.45%2BPM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="968" data-original-width="1600" height="386" src="https://4.bp.blogspot.com/-ePDyDM3FPsw/WexQlRcNRPI/AAAAAAAAqb0/9l7gxh03-GkWxs_IKCKcBDxeDvzNpYBSgCLcBGAs/s640/Screen%2BShot%2B2017-10-22%2Bat%2B3.01.45%2BPM.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">上批踢踢得到一堆回應說我是大肥羊的親友保單規畫,截圖沒包含一年約十三萬的外幣儲蓄/投資保單</td></tr>
</tbody></table>
於是,我除了每年要付一筆不算低的保費以外,還幾乎得自付對醫療可能會有較高需求的小兒子醫藥費。而大兒子幾乎規格一樣的保單,我只能說,還好我大兒子目前身體比較健壯一些,希望他們都能平平安安長大。<br />
<br />
對親戚不能百分百的信任,即使再忙,也不能輕易簽下任何契約是我在今年得到的第二個第一次裡,所學到最寶貴的一堂課,我很容易全心全意地信任一個人,可是信任一旦被破壞,信任的牆也很難被補好。<br />
<br />
屋漏往往就是會逢連夜雨,因為我上一間號稱是東南亞臉書的公司有了財務危機,公司表示薪資較高的人員將暫緩發放薪資 (不要誤會,我的薪資沒有到很高),下個月就會補足,而這個所謂的下個月,從一月一直等到今天,始終還是沒能等到。儘管後來美國那邊有新聞稿傳出被收購,結局卻峰迴路轉變成破產倒閉,人生第一次被倒債就被倒了一筆將近便宜國產車的金額,還被為數不小的萬惡房貸追著跑的我,也只能趕快把自己存的幾筆安全定存提早解約,然後趕快收拾心情找工作維持家計。<br />
<br />
第三個第一次就是人生第一次被欠薪,然後公司收了。一間有很棒的人的很棒公司卻倒了,實在有點可惜。<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-W3l2cmTKEO8/WexaP0wQR_I/AAAAAAAAqdE/g8OjcLP6cZ8m0PeLagSSzo6Dbc7pEMhswCLcBGAs/s1600/Screen%2BShot%2B2017-10-22%2Bat%2B3.42.07%2BPM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="990" data-original-width="1600" height="394" src="https://1.bp.blogspot.com/-W3l2cmTKEO8/WexaP0wQR_I/AAAAAAAAqdE/g8OjcLP6cZ8m0PeLagSSzo6Dbc7pEMhswCLcBGAs/s640/Screen%2BShot%2B2017-10-22%2Bat%2B3.42.07%2BPM.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">在 591 搜尋租屋搜到辦公室之前新裝潢時的照片,不免有些感傷</td></tr>
</tbody></table>
第四個第一次則是當總招跟佈置,等老姐結婚等了三十幾年,也在這神奇的一年發生了,從幫忙買淘寶不斷吵架,到婚禮當總招忙到焦頭爛額,感謝老天,在那段要忙小孩、面試工作、幫忙準備婚禮、小叔叔剛好過世多頭燒的辛苦日子終於讓我撐了過去。<br />
<br />
由於不想讓家人擔心,直到我快找到了工作、事情都結束了才跟他們透露公司的情況,心理素質應該有越挫越勇的感覺,只不過那時候因為心理壓力可能常對家人發脾氣,這點我對他們也有些抱歉。<br />
<br />
說到了婚禮,不由得還是得感嘆一下,當我被約好要當人生第一次的伴郎不久後,就因為自己突然閃婚而得提前跟好朋友取消,所以在知道自己人生當不成伴郎後,認命地將志向轉往立志成為新人們最佳、最安全的開車駕駛。<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-PCmjTTPGMPM/WexR4SExBbI/AAAAAAAAqcM/jHbkF1uwBq4cL6FA0s9bSGzVSLsVDmkmwCLcBGAs/s1600/20170331_192157.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="900" data-original-width="1600" height="360" src="https://1.bp.blogspot.com/-PCmjTTPGMPM/WexR4SExBbI/AAAAAAAAqcM/jHbkF1uwBq4cL6FA0s9bSGzVSLsVDmkmwCLcBGAs/s640/20170331_192157.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">前一天下大雨的文山農場晚上,爬上爬下的佈置</td></tr>
</tbody></table>
第五個第一次就是申請失業補助和參加申請失業補助時會強迫上課的就業講座。至於參加講座時只對我們爛法律問一個問題就把講師問倒、顯示失業補助講座再辦幾百場都沒有比修改對勞工有保障的法律還有效的心得就又是另一個故事了。<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-rZk7Y0Q9fN8/Wexa_yIIa6I/AAAAAAAAqdM/LMw8vxaCrtofs3v7pZWWilh7JsPLHqdCwCLcBGAs/s1600/20170614_110340.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="900" data-original-width="1600" height="360" src="https://1.bp.blogspot.com/-rZk7Y0Q9fN8/Wexa_yIIa6I/AAAAAAAAqdM/LMw8vxaCrtofs3v7pZWWilh7JsPLHqdCwCLcBGAs/s640/20170614_110340.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">沒有什麼用的就業講座</td></tr>
</tbody></table>
所幸在這個軟體工程師還算好找工作的年代下,在台灣順利地拿到了幾個不錯的 offer。But,人生往往最關鍵的就是這個 But,難得在台灣可以拿到一些漂亮的 offer (對我這種小弱弱來說) 的我,最後卻硬是不聽嶺頂觀音寺菩薩給的「不宜遠遊」的警告,選擇了薪資相對比較低 (因為台幣一直狂升)、要等兩個月工作簽沒薪水、遠赴到<a href="https://www.andretw.com/2017/07/work-in-thailand-work-permit-visa-non-immigrant-b-apply.html" target="_blank">泰國的 agoda 工作</a>。<br />
<br />
所以我的第六個第一次就是出國面試和出國工作。<br />
<br />
在 agoda 的工作經驗是我人生一個相當棒的體驗,員工來自將近六十國的多樣組成、國際化的大都市、舒服的租屋環境、令人回味的美食、豐富的度假娛樂休閒、沒有規定就是泰國的一種規定等等的文化,讓我這金魚腦裡的美好時光著實豐富了不少。<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://4.bp.blogspot.com/-m7oD4oJjcgc/Wexb7dhtNOI/AAAAAAAAqdY/KdcSRRqBEXMt69d5Xnl_4USpHy0V9fNXgCLcBGAs/s1600/20170630_224455.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="900" data-original-width="1600" height="360" src="https://4.bp.blogspot.com/-m7oD4oJjcgc/Wexb7dhtNOI/AAAAAAAAqdY/KdcSRRqBEXMt69d5Xnl_4USpHy0V9fNXgCLcBGAs/s640/20170630_224455.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">前一晚準備出發兩隻小隻的在旁邊一直干擾我收行李</td></tr>
</tbody></table>
但是菩薩說的「不宜遠遊」不知道是否是算到了我身體會出現狀況?<br />
<br />
本來以為是中暑的症狀,第七個第一次則是在貴森森的曼谷高檔醫院檢查。所幸公司的保險福利不錯,就醫幾乎不用自費負擔 (但是曼谷的醫院喜歡看你的保險買多貴,診療費就會幾乎是把你的給付額度用到完或多一點),但是身體持續不舒服的我,雖然才剛從台灣飛回曼谷幾天,立刻上網買了隔天的機票飛回台灣,預約先前定期追蹤檢查的醫生治療。急性發作的肝炎讓我幾乎吃不下任何東西,一個多月的時間讓我瘦了近十公斤,雖然減肥很棒,但是這樣聞到油煙味就想吐的感覺真的不想再有了。<br />
<br />
這第七個第一次再次地讓我體會到了身體健康的重要。<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-LbAUhquq0b0/WexdByUDFoI/AAAAAAAAqdo/KkDjWq2PrkoiN6LZVzRzBcg-M6DXlJR2ACLcBGAs/s1600/Screen%2BShot%2B2017-10-22%2Bat%2B3.54.57%2BPM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="324" data-original-width="630" height="328" src="https://3.bp.blogspot.com/-LbAUhquq0b0/WexdByUDFoI/AAAAAAAAqdo/KkDjWq2PrkoiN6LZVzRzBcg-M6DXlJR2ACLcBGAs/s640/Screen%2BShot%2B2017-10-22%2Bat%2B3.54.57%2BPM.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">發炎指數很高的檢驗書,回到台灣等一個禮拜後報告指數破表</td></tr>
</tbody></table>
第八個第一次則是在 ATM 領錢,插成信用卡又碰巧遇到機器故障重開機的事件。如果只是機器突然重開機把我卡片吃掉那還好 (相較之後發生的蠢事),當時我誤以為是我的 ATM 卡被吃掉,於是我還立刻打電話通報花旗銀行我的 ATM 卡被意外吃掉了。聰明的看倌可能會有注意到蠢點在哪,就是我打電話去中止了在我皮包裡頭的 ATM 卡,而被吃掉的卡片則是我的信用卡,最後就是導致我身上所有的花旗卡都失效的尷尬情況。(當時我把信用卡插進去打錯了密碼按了取消,它就把我的卡給吃下去了,我的信用卡支持預借現金功能,真的不是因為我插錯卡只打錯了一次密碼被吃,下面有 ATM 重開機的圖......)<br />
<br />
之後每跟工作人員解釋一次,就得陪對方笑一次,實在真的覺得自己有點蠢......當時身上現金已經要燃燒殆盡的我,還好有同事可以借錢過生活,不然我那時可能連土都沒辦法吃了......在泰國,真的什麼神奇的事情都會遇到,什麼都不奇怪。<br />
<br />
不過就在事件發生兩天後的剛剛,我在 Central World 的花旗銀行順利拿到了兩張全新的卡片,花旗的行員在看到護照上面的出生日期,同時也注意到了日期是今天,於是她對我說了聲生日快樂,心裡突然一陣暖暖的。她也可能成為了今天唯一有對我當面說到生日快樂的人,哈哈,因為我有點低調沒讓人知道今天是我生日,本來想要請假卻因為手上有些任務沒做完只好乖乖去上班,嗚嗚。<br />
<br />
這裡有個題外話,本來我是普通 ATM 卡最後變成了一張含有 Debit Card 功能但我卻不想要的卡片,雖然我在泰國這邊沒有 Master Card,但是這樣卡片就會變成有效期限制,每隔幾年就要強迫換新但我卻不知道人有沒有在泰國了......<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-NzfQ_wJoJ5Q/We1C6CB4BYI/AAAAAAAAqe4/QZS5HrcyYh85Mbxd73Sl3JPHlLBX_ZD3ACLcBGAs/s1600/Screen%2BShot%2B2017-10-23%2Bat%2B8.14.55%2BAM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1166" data-original-width="1600" height="466" src="https://3.bp.blogspot.com/-NzfQ_wJoJ5Q/We1C6CB4BYI/AAAAAAAAqe4/QZS5HrcyYh85Mbxd73Sl3JPHlLBX_ZD3ACLcBGAs/s640/Screen%2BShot%2B2017-10-23%2Bat%2B8.14.55%2BAM.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">在 MaxValue 裡會故障當機吃掉卡的 ATM 機器,打電話去客服好像大家稀鬆平常我是大驚小怪</td></tr>
</tbody></table>
第九個第一次就是我跑去了 GoGobar 玩。曼谷市中心沒幾站就到了 GoGobar 的熱門集散地,花個幾百塊就可以看到一些有趣的東西,只能感嘆為什麼台灣不能早點合法化呢?(雖然泰國法律上仍是不合法,但是他們有著一些平衡) 學新加坡合法之後集中管理,不但可以強制做健康檢查還可以有一筆龐大的稅收不是很好嗎?<br />
<br />
台灣就是有一群假道學的人,以為眼睛閉上就可以忽略掉人性對性的需求。<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-VtRI0FFnpiU/WfCDIZHooxI/AAAAAAAAqjU/vww7HzQD5EkhhCWyKzmQG9Ij0wC_2DqUwCLcBGAs/s1600/20170424_222715.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="900" data-original-width="1600" height="360" src="https://1.bp.blogspot.com/-VtRI0FFnpiU/WfCDIZHooxI/AAAAAAAAqjU/vww7HzQD5EkhhCWyKzmQG9Ij0wC_2DqUwCLcBGAs/s640/20170424_222715.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">BTS NA NA 站附近的 GoGobar 集中區 </td></tr>
</tbody></table>
第十個第一次則是我好不容易通過了泰國規定漫長的試用期後,決定要離職回台灣工作了。<br />
<br />
嗯,是的,你沒看錯,我決定要回台灣去了。<br />
<br />
在回到曼谷後,從 LinkedIn 收到了幾間來自台灣新創的邀約,本來也沒想太多,就單純想聊看看台灣現在的新創在做些什麼,其中遇到了個題目是我從以前就很想做的東西,雖然可能現在的市場有些紅海,但是他們靠著可能成功的突破點 (同時也是我以前想做的東西),聽到有人真的出資想把它實現,還願意完全授權給我發揮,那一刻,我心動了。<br />
<br />
「機會是不等人的。」這是一位前輩在我分析我認為的優缺點後,說出了一句雖然很常聽到,卻是最後讓我下定決心的關鍵。<br />
<br />
於是,雖然台北的家已經租人,雖然我泰國租的房子違約要賠錢,雖然我還在台北租了倉庫放東西,雖然這邊的同事都很好很親切,雖然我花了很多很多心血還等了很久才來到了曼谷 ;雖然有那麼多的雖然,但是在考量身體 (真的不是 agoda 很操)、家人、生涯規劃等各種因素後,我決定回台灣和這個新創公司再一起衝衝看,儘管有可能會再一次失敗,但是我希望到了我老了之後,我能對自己輕聲說:「我沒有虛度此生。」<br />
<br />
感謝這段時間被我諮詢打擾的一堆前輩朋友,更感謝每次都在我身後接受我做瘋狂決定的家人,我愛你們,我愛泰國,但是我更愛台灣。<br />
<br />
下一步,一間美國在台灣的小新創研發總監,雖然能力可能沒有各位前輩那麼厲害,但是我會好好加油。最後也偷偷徵才一下,Front/Back-end/Android/DevOps 全都需要,拜託大家幫幫忙推薦一些好履歷。<br />
<br />
祝我自己生日快樂,也祝認識我的大家天天快樂。<br />
<br />
<br />
<br />
後記:在寫這篇文章的同時,我的額頭有些發燒,身體也有些刺癢和無力,team 裡幾個人得到了登革熱,但我不想寫第十一個第一次,拜託。<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-79106790050461103052017-07-24T00:00:00.002+08:002017-07-24T00:00:49.607+08:00到泰國工作要準備些什麼?工作簽證、工作准證申請<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/--ewn3yQBCOs/WXS_-9uUQ0I/AAAAAAAAoIw/JiztHd4aKTwrYiFJvrUaqt4Ib4Hu5UxVwCKgBGAs/s1600/20170714_105744.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1600" height="360" src="https://4.bp.blogspot.com/--ewn3yQBCOs/WXS_-9uUQ0I/AAAAAAAAoIw/JiztHd4aKTwrYiFJvrUaqt4Ib4Hu5UxVwCKgBGAs/s640/20170714_105744.jpg" width="640" /></a></div>
<br />
上一篇我寫的 <a href="https://www.andretw.com/2017/05/agoda-interview-onsite-thailand-bangkok-software-engineer-full-stack.html" target="_blank">[agoda] 泰國曼谷軟體工程師面試流程分享</a> (註1) 主要是面試過程的分享,緊接著的這篇文章,則是在紀錄拿到錄取通知 (offer) 而且下定決心要去泰國工作後,需要開始著手準備哪些文件、跑什麼流程?<br />
<br />
由於需要準備的東西著實不少,流程也可能因為各個公司專責協助的團隊而有所不同,所以這篇文章的免責聲明第一條就是:「<b>僅以 agoda 協助我的經驗與大家分享,如有不雷同之處,還請多多回饋,非常感謝。</b>」<br />
<br />
首先,要去泰國工作前必須要有的認知是,在你大量搜尋有關「<a href="https://www.google.com.tw/search?q=%E6%B3%B0%E5%9C%8B+%E5%B7%A5%E4%BD%9C+%E8%B3%87%E8%A8%8A&oq=%E6%B3%B0%E5%9C%8B+%E5%B7%A5%E4%BD%9C+%E8%B3%87%E8%A8%8A" target="_blank">如何在泰國工作</a>」的資訊後,一定會常常看到許多類似「<span style="background-color: #d9ead3;">不是難,而是非常難</span>」這樣令人氣餒的答案,當我跑過一次流程後,我深深相信真的很難。由於泰國不是一個移民國家,他們雖然很喜歡外國觀光客到泰國觀光旅遊消費,但是如果一個外國人想來泰國工作?我只能說,倘若公司沒有負責協助的團隊幫忙,這一定會是場恐怖的夢魘。<br />
<br />
有了上面的認知而且順利找到工作後,再來需要知道的是,如果想要合法在泰國工作,必須同時擁有<span style="background-color: #fff2cc;">工作簽證 (Work Visa)</span> 及 <span style="background-color: #fff2cc;">工作准證 (Work Permit)</span>。其中工作簽證/准證又有分 BOI (The Board of Investment of Thailand) 或 IEAT (Industrial Estate Authority of Thailand) 核發的 (註2),BOI 核發的福利跟年限 (最高兩年) 都比較好,由於 agoda 有 BOI 的認證,所以這篇文章的流程主要以 BOI 核發的簽證/准證為例,大致上的流程為:<br />
<ol>
<li>繳交資料給協助窗口</li>
<li>等待收到實體 BOI pre-approval letter、邀請函、公司財報資料等等文件</li>
<li>拿上面收到的實體文件到泰國辦事處辦理 Non-immigrant-B 單次簽證</li>
<li>收到簽證 <br />----- 從這之後可能每間公司會不一樣 -----</li>
<li>到了泰國之後公司會協助將 Non-immigrant-B 單次簽證轉成多次簽證 (long term visa extension)</li>
<li>到 One Stop Service Office 申請/領取工作准證</li>
<li>取得工作准證</li>
</ol>
需要準備資料則有 (注意,每間公司協助與需要的資料可能不一):<br />
<ol>
<li>錄取通知 (offer letter)</li>
<li>就業協定 (employment agreement)</li>
<li>簽證調查表 (visa questionnaire)</li>
<li>學歷證書 (copy of your education certificate)</li>
<li>學業成績單 (transcript of your bachelor/master/doctor)</li>
<li>最新履歷 (updated resume)</li>
<li>護照影本 (copy of passport) 至少要一年有效期及六頁簽證空白頁</li>
<li>工作經歷證明 (work experience letter from your former employer(s))</li>
</ol>
<div>
上面的文件主要是公司要用來準備提供給你 BOI pre-approval letter 用的,這封信是申請 Non-immigrant-B 單次簽證的重要文件之一。另外由於泰國的個人所得稅不算低 (註4),一百萬泰銖以上的個人所得稅就要科 25 %,兩百萬泰銖以上則高達 30%,上面如學歷證書、成績單及工作經歷證明等等,除了用來申請工作准證以外,也是一種申請 flat-rate tax 的證明 (Qualification of 15% flat-rate tax benefit),可以讓辛苦賺到的個人所得稅負稍微降低一些。所以公司能不能申請 flat-rate tax 也是在決定是否要前往泰國工作前,一個需要慎重考量的因素。<br />
<br />
當你望穿秋水終於等到公司寄來的相關資料後 (大約三個禮拜到一個月),根據最上面的流程就是前往泰國辦事處辦理簽證,辦理工作簽證與跟旅遊簽證排隊的地方不一樣,要問一下避免浪費時間。把資料都交給辦事處人員後,隔天下午就可以取件了 (也可能是因為現在免簽證費很多人申請旅遊簽證,之後沒免簽證費後,人潮不多就可能可以當天下午拿到了吧)。<br />
<br />
基本上取得了 Non-immigrant-B 的簽證之後,唯一要注意的只剩下入境的時候要注意簽證有沒有被蓋章顯示已使用 (USED),還有出境卡不要弄丟 (這個聽說九月 (2017) 有可能會有改動),不過由於台灣還沒有免簽,所以應該還不會發生簽證沒被蓋到已使用的章這種情況。<br />
<br />
接下來我們公司的情況是在第一天就會開始協助你辦理改成多次簽證及申請工作准證,約是到職兩個禮拜後左右的時間,要到移民局那邊進行辦理相關的手續 (在曼谷我們是去 OSSO),通常是一個上午左右的時間就會完成,只是跟我同時報到的外國同事很多,我們那天從早上九點一直用到了下午三點左右才回到了辦公室。然後就會得到了一本兩年期的工作准證和一個兩年期的多次入境簽證。這邊還有另外一個要注意的是,入境後每九十天都要跟移民局進行一個報備的動作,關於這件事,我們公司有自己的一套流程跟提醒的機制,所以這也要看每間公司的處理狀況了。<br />
<br />
總之,以上就是在泰國辦理工作簽證跟工作准證的流程,處理完後,就可以安心的在泰國工作跟申請銀行帳號、信用卡、電信等等服務了,至於在我們公司任職後續還會需要考慮到一些保險跟稅金的問題,有機會再開另外的文章來寫好了。至於總結的心得就是回歸到開頭寫的一樣,如果沒有專屬的協助,那些步驟執行起來一定會是場夢魘,啊,對了,還有要習慣這裡輕鬆迷人的步調。<br />
<br />
<b>參考文章:</b><br />
<ul>
<li>註1: <a href="https://www.andretw.com/2017/05/agoda-interview-onsite-thailand-bangkok-software-engineer-full-stack.html" target="_blank">[agoda] 泰國曼谷軟體工程師面試流程分享</a> 這篇文章同時也幸運地被 <a href="https://blog.mit.jobs/posts/80" target="_blank">mit.JOBS 轉載</a></li>
<li>註2: Work Permit and Visa<br /><a href="http://www.better-account.com/en/Visa2.php">http://www.better-account.com/en/Visa2.php</a></li>
<li>註3: R: [問題] 老公被外派泰國,申請依親簽證問題<br /><a href="https://www.ptt.cc/bbs/Thailand/M.1497605351.A.10F.html">https://www.ptt.cc/bbs/Thailand/M.1497605351.A.10F.html</a></li>
<li>註4: Personal Income Tax<br /><a href="http://www.boi.go.th/index.php?page=personal_income_tax">http://www.boi.go.th/index.php?page=personal_income_tax</a></li>
</ul>
</div>
Unknownnoreply@blogger.comtag:blogger.com,1999:blog-4783512064634308801.post-68256413293808529642017-06-08T13:34:00.001+08:002017-06-09T16:37:14.802+08:00我讀「果凍筆要買嗎?」後感<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-cGLtyHDHQ1c/WTjcG2JdM5I/AAAAAAAAmG0/SaVV1oXXiNglm5dwQgsszLgZCWwOrHXpgCPcB/s1600/581f2129-3ffe-49ac-ae01-e64598874ff3.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="400" data-original-width="400" src="https://3.bp.blogspot.com/-cGLtyHDHQ1c/WTjcG2JdM5I/AAAAAAAAmG0/SaVV1oXXiNglm5dwQgsszLgZCWwOrHXpgCPcB/s1600/581f2129-3ffe-49ac-ae01-e64598874ff3.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">本來就很紅最近更紅的果凍筆</td></tr>
</tbody></table>
<br />
「<a href="https://flipedu.parenting.com.tw/article/2088" target="_blank">果凍筆要買嗎?</a>」這篇文章的核心就是我一直擔心華國教育而想帶小孩出國唸書的主要原因,因為「直接禁止」這種行為早就已經是一個深入華國教育體制 (註1) 骨髓、全然不知節省自己教育時間卻可能造成嚴重後果的反射動作了。最後文章結尾有提供兩個由林于倫老師所撰寫的<a href="https://www.facebook.com/outyouty/posts/10155180832346061" target="_blank">臉書貼文</a>和他精彩<a href="https://www.facebook.com/outyouty/posts/10155187670781061" target="_blank">Q&A回覆</a>的連結,內容與我的教育理念相當契合,是兩篇相當值得參考學習的文章。<br />
<br />
在華國偉大教育體制下從來不缺「直接禁止」的例子,像是馬路上遍佈沒有用腦子想就亂畫的禁行機車及兩段式左轉規定,主事者以為施行後就可以降低機車三寶的失事率,卻沒有想過其他國家設計是用車速分流而非車種來分流,結果呢?機車被迫行駛在外側車道,不但需要閃避瘋狂切換車道的公車與小黃,還得注意違規停車會不會突然開車門,因此導致更嚴重的意外不斷發生。<br />
<br />
或之前熱門的「學校是否需要繼續規定統一每天穿制服」議題,穿制服的好處是學生不用再想今天要穿什麼,因此學生從此之後就再也不會 (不需要) 比較,反正大家都一樣,較低收入的家庭學生也不會再受到歧視與霸凌,虛榮心什麼的奇怪心態當然也就自然而然地會消失不見,然後一群人就可以開始過著幸福快樂的日子。<br />
<br />
<b>才怪。</b><br />
<br />
結果是我們缺少了從小培養對自己穿著的美感,接著學生們開始比的的確不是衣服上的酷炫時髦,而是比較用了什麼新手機,打了什麼新電動;學校發現後決定亡羊補牢,採取的措施則是開始禁手機跟電動。這樣的循環直到新玩意都被禁光或學生藏得好不被發現為止。<br />
<br />
虛榮跟比較是會一輩子持續的,崇富與炫富也不是直接禁止就可以阻絕的,那是需要一連串價值觀與思辨的教育,而這樣的教育責任當然不只在學校,家庭和社會往往有更大的責任。<br />
<br />
有些奢侈品名牌會貴,撇開一些炒作因素來說,是因為它們有的有那些價值,例如衣服的版型穿起來就是又瘦又帥材質又舒服,手提包就是手工縫線製作精巧,倘若我們只在乎價格就忽略了那些價值的存在,我們怎麼能夠期待我們的小孩,除了看表面的價格,還會在乎底下那看不見的價值呢?<br />
<br />
如果駕照考核不再像以前一樣無腦簡單,搭配嚴格的違規扣點制度以及交通號誌設施重新規劃等等,雖然曠日費時,也需要耗費龐大的財力精力,難道這不才是解決問題的根本辦法嗎;學校不再強制要求學生穿制服,uniqlo 跟 lativ 也是可以穿得很時尚舒服便宜,或像我一樣,一直輪流穿幾件 t-shirt 來過完一個禮拜又有什麼關係?難道明星學校的學生愛穿著學校的制服到處跑,一點也不是因為虛榮感嗎?我們從來就不該剝奪小孩學會自己做決定的權力,或者一直讓學習的時程被延遲到大學,以致讓孩子們有了拒絕負責自己決定的藉口。<br />
<br />
所以,連筆都要用威權式的教育而不讓他們學會選擇 (註3) 之後,孩子們不能在學校這種允許犯錯的環境中學習,那我們該讓孩子們在什麼時候開始學呢?連 AI 在不久的將來都有可能判斷什麼才是美、什麼才是舒服的激烈競爭環境下,我們卻讓我們的小孩連自主選擇能不能用 200 元價格的筆 (註2) 都不能時,那該如何期待我們的孩子與未來聰明的 AI 競爭呢?現在其實是個值得紀念的時刻,當 <a href="http://www.smh.com.au/technology/technology-news/apple-wwdc-10yearold-app-developer-from-melbourne-meets-tim-cook-20170605-gwkejp.html" target="_blank">10 歲的小男孩在全世界萬眾矚目的 WWDC 被介紹</a>、澳洲政府把 iPad 當作小學的必備 (送) 品時,我們的教育仍有許多人會選擇直接 (贊成) 禁止學生帶高單價的筆去學校。<br />
<br />
或許身為老爸的我也做得不是很好,但「<span style="background-color: #fff2cc;">學會如何選擇以及對自己的人生負責</span>」是我希望我兩個小兒子未來能夠用心好好學習的課題。我也希望他們知道爸爸從來都不是所謂的乖乖牌,在學校、在軍中都曾經跟不合理的規定戰鬥過,所以我鼓勵我的孩子們跟我、跟體制衝撞。對我來說,沒有衝撞,哪看得到燦爛的火花呢?<br />
<br />
<br />
<b>後註與相關文章:</b><br />
<ul>
<li>註1: 簡單的說華國教育體制就是喜歡當保姆,什麼都想規定,不希望你學會思考,因為我是對你好,所以幫你做的選擇也是最好的,你就得乖乖吞下去。</li>
<li>註2: 如果學生自己學會上網團購談判爭取更低的價格,對我來說也是一種不錯的學習方式。</li>
<li>註3: 其實我提到的「選擇」,其實是隱含的是我們對「自主思考」這件事的重視程度,會做出很多威權父長式的規定,是因為他們主觀認為他們的聽眾不懂得自主思考,思考也都會是錯誤的。</li>
<li><a href="https://flipedu.parenting.com.tw/article/2088" target="_blank">果凍筆要買嗎?</a> (文章下面有許多留言很值得參考學習)</li>
<li><a href="https://www.facebook.com/outyouty/posts/10155180832346061">https://www.facebook.com/outyouty/posts/10155180832346061</a></li>
<li><a href="https://www.facebook.com/outyouty/posts/10155187670781061">https://www.facebook.com/outyouty/posts/10155187670781061</a></li>
<li><a href="https://buzzorange.com/2017/06/07/sick-roc-eeducation-attitude/" target="_blank">孩子用 200 元果凍筆太奢侈?他點出「毛骨悚然」的台灣教育:用愚民思維扼殺孩子美學</a></li>
</ul>
<div>
<br /></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-46739331531837130652017-05-29T21:02:00.002+08:002022-11-29T14:36:19.743+08:00[agoda] 泰國曼谷軟體工程師面試流程分享<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://4.bp.blogspot.com/-hKPYbd_mbTg/WSwz4UezknI/AAAAAAAAl7k/XBIoV1-UFx8mjyQcSrbMAZ0mnAskjtFtwCLcB/s1600/Screen%2BShot%2B2017-05-29%2Bat%2B10.44.06%2BPM.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1082" data-original-width="1422" height="486" src="https://4.bp.blogspot.com/-hKPYbd_mbTg/WSwz4UezknI/AAAAAAAAl7k/XBIoV1-UFx8mjyQcSrbMAZ0mnAskjtFtwCLcB/s640/Screen%2BShot%2B2017-05-29%2Bat%2B10.44.06%2BPM.png" width="640" /></a></td></tr>
<tr><td class="tr-caption">門禁森嚴需要多次換證,內部不能拍照的總部門口</td></tr>
</tbody></table>
<br />
今年 (2017) 三月左右,Booking.com 在台灣有舉辦一些交流活動,參加活動完後讓我對線上訂房產業與技術產生了些許興趣,雖然有收到 Booking.com recruiter 從 LinkedIn 上寄來的面試邀請,但內心可能還存在著一些創業魂及對東南亞的興趣,暫時婉拒了這個機會,在工作的選擇上,我還是偏愛尚未成為產業龍頭並且還有龐大成長空間的公司,所以剛好看到同屬 <a href="https://www.forbes.com/sites/genemarcial/2017/05/11/expect-priceline-to-hit-new-highs-as-travel-service-leader/#7be3b8423a52" target="_blank">Priceline 集團</a>、網站風格卻還像新創公司的 agoda 在招募 Full Stack Engineer 的廣告時,儘管職缺上提到的 C# 我從來沒用過 (註1),還是不管三七二十一就在線上提交了申請。<br />
<br />
在面試流程開始介紹前,先大略提一下我個人的背景,也會把與面試相關的日期標註在後面,希望這篇文章可以幫助到一些想去泰國曼谷工作的朋友在事前做一些準備。<br />
<br />
約十年前我從某國立大學數學系畢業,應屆在某國立資工所待一個學期、修了十五個學分後決定肄業當兵去。退伍自己跑去歐洲玩幾個月後回來分別在某半官方資訊法人、防毒軟體公司、NAS 公司、以及號稱<a href="http://company.mig.me/%E6%9C%88%E5%A2%9E130%E8%90%AC%E4%BA%BA-migme%E8%BA%8D%E5%8D%87%E5%8D%97%E4%BA%9E%E6%9C%80%E5%BC%B7%E8%87%89%E6%9B%B8/" target="_blank">東南亞臉書</a>的 Social Network 工作過。工作職涯初期主要都是以 Backend 為主,近期則主要以 React.js 和 Vanilla JS 維生,不久前蠻常在 <a href="https://stackoverflow.com/users/1793682/andre-lee" target="_blank">Stack Overflow</a> 上打混,有一些像籃球裁判、<a href="https://www.andretw.com/2014/06/2014-foreign-language-tour-guide-exam-and-interview-Taiwan.html" target="_blank">外語導遊</a>等跟軟體工程師不相關的證照,年輕的時候曾經參加過一些黑客松拿了一些小獎項。在面試前對泰國的認識只有分別去過曼谷和普吉島各一次,英文等級指考時是高標,但單字能力逐年迅速遞減;泰文跟很多人一樣只會「沙挖滴卡普」,其他什麼都不會。大致上是這樣,如果想知道其他工作過的細節,歡迎加我的 <a href="https://www.linkedin.com/in/andretw/" target="_blank">LinkedIn</a> 交個朋友。<br />
<br />
在線上投履歷大約一兩個禮拜後就接到了 HR 的面試邀請通知 (MAR 22nd),在約三封電子郵件的往來確認後,確定了第一次線上 Skype 面試時間 (MAR 29th)。面試完第一輪約一小時的面試後,下午很快就收到了第二輪的面試邀約,因為剛好碰上清明連假和要幫忙我姊的婚禮 (APR 1st),我約在清明節 (APR 5th) 下午挑戰我的第二輪面試。第二輪面試也是約略一個小時,最後以一個系統架構設計的問題結束。約莫三小時後就收到了 on-site 面試的邀請,效率高到讓人有點不可思議,只是那時候我還有其他的事情要處理,跟人資討論好幾次後,才決定在過了潑水節的後一週 (APR 20th) 出發,後來想想,如果沒被錄取又沒參加到潑水節好像就真的有點可惜了。至於在面試的日程安排上,通常 agoda 會讓應試者在抵達泰國後的隔天再讓應試者休息一天,也就是到了泰國後的第三天才會進行面試,但是由於我到的日子是星期四,第三天會是沒人在的星期六,所以只好隔天就硬著頭皮參加連環面試大挑戰了。<br />
<br />
<span style="background-color: #fff2cc;">這邊插播一下關於申請泰國簽證的注意事項,泰國近期 (MAR 2017) 對台灣仍然沒有免簽,雖然免旅遊簽證手續費,但是自己去排隊辦旅遊簽證的過程簡直是場折磨,要不是因為出國的日期太趕,我一定會選擇花台幣兩三百元請人代辦,兩三百真的很划算,當你看到那擠滿辦事處的排隊人潮,不但會悔恨自己為什麼沒有請代辦,連想滑手機滑到沒電都還得怕跳號過頭而滑得不安心,更別說送件跟取件總共還要浪費兩次。那在申請表單上要選擇辦什麼種類的簽證呢?因為我想我總共六天待在泰國,只有一天下午在 agoda 聊天,其他時間都在觀光旅遊也沒有工作,所以最後選擇申請旅遊簽證應該沒錯。</span><br />
<br />
基本上 agoda 會提供三到四天的免費住宿給應試者 (註2),可以依個人需求與 HR 討論去回程機票日期,只要自己負擔額外的飯店費用,就可以在面試結束後多待泰國玩一下了。從機場到飯店的交通也不用擔心,agoda 會安排專屬轎車 (limousine) 從機場接送到飯店,住的飯店通常會離市中心的總部很近,大約走十分鐘左右就可以抵達,搭車從機場到飯店雖然蠻舒服的,地處市中心也相當熱鬧,不過缺點就是塞車會塞到天荒地老讓人想下車用走的。由於我隔天就要面試,所以在面試的前一天晚上我有自己先走一遍試算路程時間兼探路,不然正式面試前還得找路搞得自己滿身大汗就有點狼狽了,面試最不缺的就是緊張,事前能多做一些準備總是好的。<br />
<br />
我的 on-site 面試 (APR 21st) 有四關,每個職位的經驗可能不一樣,每關也是大約一個小時,兩關結束後會接著有一個鐘頭的休息時間,然後再繼續面試兩關。也就是如果從下午一點開始,就會一直面到下午六點才能解脫。這裡值得注意的是,面試官的名字跟當天的面試行程 HR 會在出發前跟應試者確認,收到行程表後我有偷偷 Google 人肉了一下面試官,查一下過去的專長與過往的經歷,猜測可能會問哪些問題,最後我自己感覺是還蠻有效的,至少看到面試官不會有那種第一次看到的陌生感,對我來說也比較不那麼緊張。<br />
<br />
話說回來,我這次面試的經歷也算蠻特別的,因為第一關的面試官不知道為什麼時間到了還找不到人,所以我的第一關是在會議室跟 HR 的聊天中度過,聊天時她雖然有一直不停地跟我道歉,或許這個聊天有稍微舒緩了一下我緊張的心情,但因為不知道 HR 會不會也偷偷在這時候對應試者打分數,所以雖然表面上是閒話家常,也還不敢隨便造次就是了。而這面試過程中唯一讓我有小小抱怨的是原本以為自己可以少面一關賺到了,但是後來第一關的面試官臨時改在中間的休息時間進行面試,本來可以休息的一小時卻變成了得連續五小時不停講話和燒腦奮戰。<br />
<br />
On-site 的面試有白板題,內容有<b>演算法</b>、<b>系統架構</b>、<b>設計模式</b>、<b>除錯經驗</b>等等,比較值得注意的是體力真的要足夠,在面到最後一關時,有可能會有開始放空的情況產生,但是雖然有時候會放空,沒聽懂的部分還是要勇敢地再問一次,不然回答錯就糗了。所以我覺得可能在面試前買個<b>巧克力</b>或<b>咖啡</b>之類的<b>提神</b>食品,在換下一個主考官進來前迅速補充一下,或許或多或少可以讓精神在最後一兩關的時候集中一些。<br />
<br />
在機場準備搭飛機回台北的路上,收到了 HR 跟我說 manager 要跟我約談 feedback 的郵件 (APR 25th),心裡其實有點忐忑不安。不過還好隔天 (APR 26th) 幸運地拿到了口頭錄取通知,在經過一個多禮拜 (May 5th) 的長考後,決定前往曼谷工作。最後錄取的職位是 Senior Full Stack Engineer,工作內容著重於 Web 的 Backend 和 Frontend 的設計與架構實作,相關或其他職位的面試問題可以去 <a href="https://www.glassdoor.com/Interview/Agoda-Interview-Questions-E461386.htm" target="_blank">Glassdoor</a> 做一下研究,裡面有很多前輩寫的有用資訊。為什麼會做出這樣的決定?或許我一輩子反骨慣了,想要在短短人生有更精彩豐富的體驗,常常做出別人覺得是改變蠻大的決定,雖然同時拿到了其他在台外商不錯的 offer (單純以薪資不計算生活水平之類而言是比 agoda 好),我還是決定舉家搬遷去曼谷作為我人生的下一步,至於很久沒用的 Windows,就當作另一種對自己的挑戰吧 :D<br />
<br />
對了,agoda 有提供一些 relocate 的 package,像是第一個月會提供應試錄取者不錯的酒店式公寓讓你去找房子 (註3),還提供一個貨櫃可以讓你把家裡的東西都搬去曼谷、幫家人辦簽證等等。<br />
<br />
下一篇文章會是申請<b>工作准證 </b>(Work Permit) 和<b>工作簽證 </b>(Visa) 的經驗分享,如果是有經驗的工作者,為了申請減免泰國的高額個人所得稅 (註4) 和工作准證,需要準備的資料會有些繁雜,提早知道可以提早申請準備資料,不然拖到後面的進度你會發現申請的時程慢到像是在測試應試者的耐心一樣。另外在決定前往泰國工作前也需要事先評估一下當地的消費、租房和孩子們的教育 (註5) 等等生活雜事,這在接受 offer 前絕對需要下一番工夫好好研究,所幸在有疑問時靠谷歌大神還有一些前輩朋友們的幫忙,讓我能夠像打怪一樣一關一關突破,所以之後有空也會針對這些相關經驗寫一篇心得來回饋分享。<br />
<br />
如果想要了解一下考試題目,批踢踢 Soft_Job 版有兩篇寫得不錯的面試題分享,相當值得參考學習:<br />
<ol>
<li><a href="https://www.ptt.cc/bbs/Soft_Job/M.1492257650.A.5BC.html" target="_blank">[心得] Agoda Full Stack Developer</a><br />https://www.ptt.cc/bbs/Soft_Job/M.1492257650.A.5BC.html</li>
<li><a href="https://www.ptt.cc/bbs/Soft_Job/M.1492329963.A.109.html" target="_blank">[心得] agoda senior SWE (data engineering)</a><br />https://www.ptt.cc/bbs/Soft_Job/M.1492329963.A.109.html</li>
</ol>
<div>
倘若你對 agoda 有興趣或任何問題 (註6),歡迎透過留言或是 <a href="https://www.linkedin.com/in/andretw/" target="_blank">LinkedIn</a> 聯絡我。<br />
<br />
<b>後註: </b><br />
<ul>
<li>註1:工作以來大都是走 *unix 派的,比較常用的是 Python、NodeJS、PHP 跟 Java。</li>
<li>註2:我這次去面試 agoda 提供的住宿飯店是 <a href="https://www.agoda.com/partners/partnersearch.aspx?cid=1780139&pcs=1&hid=287436" target="_blank">Novotel Bangkok Platinum Pratunam</a>。</li>
<li>註3:其實我覺得住宿部分應該跟歐洲有些公司一樣,提供整個試用期 <b>119</b> 天的長度比較好,不然如果試用期沒過還要付違約房租有點慘慘滴。</li>
<li>註4:<a href="https://assets.kpmg.com/content/dam/kpmg/pdf/2016/05/in-focus-tax-issue-4.pdf" target="_blank">泰國的個人所得稅</a>很高,一百萬泰銖以上就要 25%,兩百萬泰銖以上就要到 30% 了。</li>
<li>註5:曼谷因為有很多外商主管攜家帶眷進駐,所以有很多國際學校,先不講價錢這點的話是很吸引我。</li>
</ul>
<div>
<div>
<b><br /></b> <b>常見問題</b><b>:</b><br />
<span style="background-color: #f4cccc; font-size: x-small;">( 2019/03/26 因為從我離開到現在已經一年多了,中間我收到以及回覆很多人的問題,回到我都覺得我是 agoda 的人資了,所以我決定整理了一些常見問題回答如下)</span></div>
<div><b>
> Q1. 你為什麼只待了快五個月就離開 agoda 呢</b><b>?</b></div>
<div>
<div>
我在我離開曼谷前寫了一篇「<a href="https://www.andretw.com/2017/10/10-first-time-ever-in-2017.html" target="_blank">驚奇 2017 發生的十個第一次和我的下一步</a>」有做了一些交代和解釋,主要是因為我受到了一個我覺得產品是我一直想做的邀約,雖然現在回頭看覺得自己何苦這樣折磨自己,但回來台灣得到的經驗我覺得是非常難得和寶貴的。雖然中間很多時候會感到失望和挫折,不過新創就是這樣有苦有樂才讓人著迷嗎?尤其環境不斷地改變是未來每個人都會遇到的課題,學著處變不驚是一項必備的技能。最後我想說的是,agoda 是一間有龐大資源的好公司,如果有機會加入的話我相當地推薦,請不要輕易放棄這個機會。</div>
<div>
<br /></div>
<div><b>
> Q2. 薪資大約多少呢</b><b>?</b></div><div>由於每個人的背景、條件、職位、以及對於薪資的期望不盡相同,我只能說我覺得 Glassdoor 提供的訊息滿準確的,至於能不能再往上調就要看自己的談判技巧以及公司對你的需求程度了。</div><div>
<br /></div>
<div>
</div>
<div><b>
> Q3. agoda 有試用期嗎</b><b>?</b></div>
<div>有,根據泰國法規有四個月的試用期,我還在的時候有這項規定。</div>
<div>
<br /></div>
<div><b>
> Q4. agoda 有工作最低年限條款嗎?</b></div>
<div>至少 2017/11 的時候沒有。</div>
<div>
<br /></div>
<div><b>
> Q5. agoda 有競業條款嗎</b><b>?</b></div>
<div>
有的,不過就看你職位和接觸到的情報重要程度公司會不會找法務和你玩。</div>
<div>
<br /></div>
<div><b>
> Q6. agoda 除了年假,是否有帶薪病假或帶薪事假</b><b>?</b></div>
<div>
2017/11 時有全薪病假 30 天。</div>
<div>
<br /></div>
<div><b>
> Q7. agoda 除了 Relocation Package,福利是否有補助交通費、住宿費等</b><b>?</b></div>
<div>
就我的經驗是全部都在 Package 裡,但是每個人都不同,或許公司覺得是人才願意提供也不一定。</div>
<div>
<br /></div>
<div><b>
> Q8. agoda 聽說中午不供餐,不曉得這部分會不會影響生活開銷</b><b>?</b></div>
<div>
一定會影響生活開銷,雖然辦公室在鬧區中的鬧區,但是在 foodcourt 通常 THB 50 ~ 80 內就可以吃一餐很飽的了,吃的開銷我通常沒有很在意。</div>
<div>
<br /></div>
<div><b>
> Q9. agoda 基本上一定會有一個月年終嗎?</b></div>
<div>
Priceline 的財報在我當時還在的時候很不錯,但是因為我沒留到分紅的時間,我是聽說很不賴,應該會超過一個月就是了。</div>
<div>
<br /></div>
<div><b>
> Q10. 房租的部分是否能抵稅?</b></div>
</div>
</div>
<div>
就我印象中似乎是不行,這邊可能需要再確認。</div>
<br /><b>
> Q11. 多謝回答,我已經獲得 agoda 的 offer,準備開始辦理工作簽證,看到了你之前的文章,想問下工作經歷證明是需要請之前的公司開具英文證明嗎?</b><br />
恭喜,我之前的確是一間一間找之前公司要英文工作經歷證明的。<br />
<br />
<span style="background-color: #f4cccc; font-size: x-small;">( 2019/04/24 有些夥伴們在網路上曾經看過我的文章或和我討論過, 就職後他們也來信和我分享了更多心得, 因為我常常忙了就會忘記 LinkedIn 訊息, 所以如果有什麼問題直接跟他們聯絡會有最新的資訊喔)</span><br />
<br />
<br /></div>
Unknownnoreply@blogger.comtag:blogger.com,1999:blog-4783512064634308801.post-55436851668505853502017-03-16T21:20:00.000+08:002017-06-03T19:15:46.407+08:00Uploading Files via preSignedUrl to S3 buckets directly on AWS in JavaScript<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-m6s7aY055Lg/WMqTeWUESRI/AAAAAAAAjaY/L2A3Rg_d8NMl0FVY1hx9ZoQiHUecj68dQCLcB/s1600/Screen_Shot_2017-03-15_at_12_45_35_PM2.png" style="margin-left: auto; margin-right: auto;"><img border="0" height="218" src="https://3.bp.blogspot.com/-m6s7aY055Lg/WMqTeWUESRI/AAAAAAAAjaY/L2A3Rg_d8NMl0FVY1hx9ZoQiHUecj68dQCLcB/s640/Screen_Shot_2017-03-15_at_12_45_35_PM2.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Content-Type is an empty string, a wrong implementation</td></tr>
</tbody></table>
<br />
This post is about if you are going to do uploading files in JavaScript via preSignedUrl to S3 bucket directly on modern browsers, then something you should know before doing it.<br />
<br />
<h4>
1. There is a preflight (OPTION) request before your PUT request.</h4>
This is a basic know-how you should know. A non-simple request will send a preflight request to check the request is safe or not for a CORS (Cross-origin resource sharing) request.<br />
<br />
And it's interesting that AWS had a <a href="https://forums.aws.amazon.com/message.jspa?messageID=378603" target="_blank">bug</a> with it a few years ago.<br />
<blockquote class="tr_bq">
draganbajcic,<br />
<br />
Thank you, and everybody else, for the report. You are correct that pre-signed requests returning an error on the initial OPTIONS request. We are working on this issue and expect to add this support shortly. I don't have a timeline for the availability of the change but I will update this thread with more information when I have that. If you have any follow up questions let me know.<br />
<br />
Thanks,<br />
Carl</blockquote>
<h4>
2. Configure your S3 bucket's Response headers to allow CORS.</h4>
For modern browsers, CORS requests are restricted in some cases. So, in short, you need to make your S3 bucket has Access-Control-Allow-Origin related headers in its response. You can do it easily in a console here, <a href="https://docs.aws.amazon.com/AmazonS3/latest/UG/EditingBucketPermissions.html">https://docs.aws.amazon.com/AmazonS3/latest/UG/EditingBucketPermissions.html</a><br />
<br />
<h4>
3. Content-Type is one important parameter to generate the preSignedUrl.</h4>
I took some time to validate the answer and then made a request to ask our colleagues to correct the implementation that they missed putting Content-Type as a parameter to generate the preSignedUrl to fix the issue.<br />
<br />
If you send the request with different Content-Type from the content type you used to generate the preSignedUrl in your request's Header. You will get the following error response.<br />
<h4>
So...</h4>
There is no any HARD tech implementation here. The whole flow is "getting the preSignedUrl" and "Use it as target URL to upload files and putting correct Content-Type in your header". That's it.Unknownnoreply@blogger.comtag:blogger.com,1999:blog-4783512064634308801.post-53067469040420820432017-02-07T01:01:00.002+08:002017-02-07T01:07:15.163+08:00An Interesting Query for Google Maps App, ibp=gwp;0,7 Couple weeks ago, my friend sent us a message in our chat group. It was a link to indicate a restaurant that we are going to have dinner days after.<br />
<br />
And here is the link,<br />
<blockquote class="tr_bq">
<a href="https://www.google.com.tw/search?client=ms-android-samsung&noj=1&hl=zh-Hant-TW&v=6.9.36.21.arm64&biw=411&bih=731&entrypoint=sh/x/kp/local&q=%E7%BE%8A%E9%9C%B8%E5%A4%A9%E4%B8%8B%E7%BE%8A%E8%82%89%E7%88%90&ludocid=16397036703207802694&ibp=gwp;0,7&kgs=c51d9d8d742e15e9&shndl=-1&source=sh/x/kp/local">https://www.google.com.tw/search?client=ms-android-samsung&noj=1&hl=zh-Hant-TW&v=6.9.36.21.arm64&biw=411&bih=731&entrypoint=sh/x/kp/local&q=%E7%BE%8A%E9%9C%B8%E5%A4%A9%E4%B8%8B%E7%BE%8A%E8%82%89%E7%88%90&ludocid=16397036703207802694&ibp=gwp;0,7&kgs=c51d9d8d742e15e9&shndl=-1&source=sh/x/kp/local</a></blockquote>
If you tap the link above on your laptop's browsers, you will get this,<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://2.bp.blogspot.com/-RyhRN2ktS_E/WINUl1JCh2I/AAAAAAAAiBg/LXaZg-nCFIE7aunLnSaZGvJlQ2-mbwF1ACLcB/s1600/Screen%2BShot%2B2017-01-21%2Bat%2B8.30.57%2BPM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="339" src="https://2.bp.blogspot.com/-RyhRN2ktS_E/WINUl1JCh2I/AAAAAAAAiBg/LXaZg-nCFIE7aunLnSaZGvJlQ2-mbwF1ACLcB/s640/Screen%2BShot%2B2017-01-21%2Bat%2B8.30.57%2BPM.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Google's 404 page</td></tr>
</tbody></table>
Yep, it's a Google's 404 (Page Not Found) page.<br />
<br />
But my friend insisted that he can see the page <b>without</b> any issues.<br />
<br />
So, I turned on the developer console of Chrome and toggle the device toolbar to switch the devices.<br />
<b>BINGO!</b> The same link, the same page shows up correctly!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-ryxBY0_zFGs/WINXY9yJl7I/AAAAAAAAiBs/JEB390ssTpM3uqQ_5dXpTdURz57I13zGACLcB/s1600/Screen%2BShot%2B2017-01-21%2Bat%2B8.41.42%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://1.bp.blogspot.com/-ryxBY0_zFGs/WINXY9yJl7I/AAAAAAAAiBs/JEB390ssTpM3uqQ_5dXpTdURz57I13zGACLcB/s640/Screen%2BShot%2B2017-01-21%2Bat%2B8.41.42%2BPM.png" width="480" /></a></div>
<br />
<b>Why?</b><br />
<br />
I had some quick research by changing the User-Agent and found out the special query parameter,<br />
<blockquote class="tr_bq">
<b>ibp=gwp;0,7</b> </blockquote>
And there are two different themes I found by using <b><i>ibp=gwp;0,6</i></b> and <b><i>ibp=gwp;0,7</i></b><br />
<b><i><br /></i></b>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-OLJJ6l6OH8s/WJioyjteA7I/AAAAAAAAii8/5zrCOaUjs2sxWVCOPgfkg-ViSim87XbggCEw/s1600/Screen%2BShot%2B2017-01-20%2Bat%2B1.31.38%2BAM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://3.bp.blogspot.com/-OLJJ6l6OH8s/WJioyjteA7I/AAAAAAAAii8/5zrCOaUjs2sxWVCOPgfkg-ViSim87XbggCEw/s640/Screen%2BShot%2B2017-01-20%2Bat%2B1.31.38%2BAM.png" width="372" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ibp=gwp;0,6</td></tr>
</tbody></table>
<div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://2.bp.blogspot.com/-6xGx-abk9xM/WJio49dAm-I/AAAAAAAAijE/lzg34lCUCNY90KJIn4KWxdkEcOX3Icl0ACEw/s1600/Screen%2BShot%2B2017-01-20%2Bat%2B1.31.54%2BAM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://2.bp.blogspot.com/-6xGx-abk9xM/WJio49dAm-I/AAAAAAAAijE/lzg34lCUCNY90KJIn4KWxdkEcOX3Icl0ACEw/s640/Screen%2BShot%2B2017-01-20%2Bat%2B1.31.54%2BAM.png" width="374" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ibp=gwp;0,7</td></tr>
</tbody></table>
Done. A short and boring post has been made.</div>
Unknownnoreply@blogger.comtag:blogger.com,1999:blog-4783512064634308801.post-25460835398142129522016-11-12T20:31:00.006+08:002016-11-13T09:07:57.889+08:0010 天隨性地遠端工作小旅行 in Japan<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-sMjqn54eXKw/WCbtOxoJTNI/AAAAAAAAgZY/d5OCnXTK2Hg4IIUottDMi__l9TCVT1cSgCLcB/s1600/20161106_153242.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="360" src="https://3.bp.blogspot.com/-sMjqn54eXKw/WCbtOxoJTNI/AAAAAAAAgZY/d5OCnXTK2Hg4IIUottDMi__l9TCVT1cSgCLcB/s640/20161106_153242.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">日本人也愛去的星巴克有免費 WiFi 所以成為幾乎我每天工作的場所</td></tr>
</tbody></table>
上上禮拜一 (10/24),也是得知隔天生日卻要加班的日子 (哭)。由於工作上一年來緊迫的時程壓力,加上兩個甜蜜的小負擔把我壓得有點喘不過氣,任性地在徵求老婆的同意後,快速地在網上訂了票,再將兩個可愛的小搗蛋<strike>丟包</strike>委託給家人,就自已一個人跑到日本找日本人妻的老姊跟姊夫,過著一邊忙著將產品上線,一邊忙著用剩餘時間跟老朋友敘舊和呼吸東京日常特殊(乾燥)空氣的遠端上班族日子。<br />
<a name='more'></a><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-QF3JPwAcnQ4/WCbsTaLCD6I/AAAAAAAAgY8/xzeqhngb3REJ9Hij8TvMhkb-Ssc46X0pwCLcB/s1600/20161101_072907.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://1.bp.blogspot.com/-QF3JPwAcnQ4/WCbsTaLCD6I/AAAAAAAAgY8/xzeqhngb3REJ9Hij8TvMhkb-Ssc46X0pwCLcB/s640/20161101_072907.jpg" width="360" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">右下角的說明文字寫著 2016/10/31 開始行駛之類的話,結果司機還誤點,售票員還幫我打電話問有沒有行駛</td></tr>
</tbody></table>
到東京市區第一個需要解決的就是<span style="background-color: #f4cccc;">機場巴士</span>問題:第一天到日本,剛好遇到 10/31 才剛開始行駛的<span style="background-color: #fff2cc;">成</span><span style="background-color: #fff2cc;">田 <-> 大崎</span>路線巴士,原價 1200 日圓,提早一天上網預訂只要 1000 日圓,75 分鐘就可以到達大崎,比搭 Skyliner 還快。不過在我預訂的那天,連系統都還沒準備好,預訂車次時竟然只能選擇日期而不能選擇時間和車次,害我覺得超怪的,一直懷疑自己有沒有訂錯。此外,如果六個月內可以搭完(其實六個月搭不完也是可以買,因為總價 2000 日圓 4 張,只用兩次跟直接上網預訂的價格一模模一樣樣),可以事先上網購買 web 回數票,每趟更只要 <span style="color: red;"><b>500</b></span> 日圓,都快比我從松山到桃機搭的公車 (台幣 125 元) 還便宜了。<br />
<br />
因為是遠端工作又剛好遇上產品上線,所以這十天在日本有絕大部分時間都在拼命趕工,連中間遇到的兩個假日也是在星巴克度過的 (如果是日本的話,則多一個,星期四約跟前同事 Wally 吃飯時才知道那天是日本的<span style="background-color: #fff2cc;">文化日</span>)。<br />
<br />
再來就是關於遠端工作不得不談到的<span style="background-color: #f4cccc;">網路</span>狀況。第一天就因為 DNS 設成 Google 的 8.8.8.8 導致認證網頁都無法開啟,當時沒想到是這個問題,於是想到用手機上網再接 cable 分享網路給電腦來解決,但這樣做網速不知道為什麼連 VPN 會是場悲劇,所以第一天的工作環境著實令人有點想哭。但解決 DNS 的問題之後,除了日本人的放假日會跟我搶網路以外,基本上都是用得很順,嗯,沒有到很快,但是還算順。<br />
<br />
不過說實話,這次相對之前來日本的經驗,也許因為東京即將要舉辦奧運了吧,免費 WiFi 的提供點越來越多了,跟先前的記憶相比,真的有逐漸不用買 sim 卡的感覺。<br />
<br />
坐在餐廳裡的時候,我也喜歡注意一些無聊的小細節,像是待在星巴克就會注意到日本人其實也很喜歡待在星巴克裡一整天 (麥當勞也有提供 free Wi-Fi,但是星巴克跟蘋果一樣就是潮),而且在這幾天裡,整間星巴克都只有我是點<span style="background-color: #fff2cc;">特大杯 size (vanti) 的咖啡</span>的,大部分的人通常最多只點到中杯 (tall) 而已,難怪日本人都那麼瘦 (無誤)。再來就是廁所都一定超少,很多店裡都是男女共用一間廁所而已,所以廁所外常常都是一直排、排不停的人龍;最後則是桌子的高度每間分店都很統一,完全不適合上半身長的人,腰跟脖子都要一直彎著,很累。<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://4.bp.blogspot.com/-PpX1YzhTXoY/WCbxYxLGjUI/AAAAAAAAgZg/SldE54kaROsaKskAAe_slVPUF1UpL6YugCLcB/s1600/201611%25E6%259C%2588%25E2%2597%2586%25E6%259D%25B1%25E4%25BA%25AC_855.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://4.bp.blogspot.com/-PpX1YzhTXoY/WCbxYxLGjUI/AAAAAAAAgZg/SldE54kaROsaKskAAe_slVPUF1UpL6YugCLcB/s640/201611%25E6%259C%2588%25E2%2597%2586%25E6%259D%25B1%25E4%25BA%25AC_855.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">下北澤路邊容易錯過的高級星巴克</td></tr>
</tbody></table>
關於星巴克還有另外一個有趣的體驗可以說說,那就是在<span style="background-color: #fff2cc;">下北澤</span>的 Starbucks Reserve (星巴克典藏咖啡),這間位於下北澤的 Starbucks 是日本少數的特殊星巴克 (台北的則是在忠孝敦化站附近新改裝的龍門門市?),不仔細看你可能都會忽略它是星巴克。<br />
<br />
不但餐點好吃,而且,<br />
這間星巴克是有賣酒的、<br />
這間星巴克是有賣酒的、<br />
這間星巴克是有賣酒的!<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-JjWCf5RZ1Ek/WCbxnZbaB1I/AAAAAAAAgZk/kH9IBYXFRJI-XA2E3BoVoHiPA9rCfIkvQCLcB/s1600/201611%25E6%259C%2588%25E2%2597%2586%25E6%259D%25B1%25E4%25BA%25AC_8284.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://3.bp.blogspot.com/-JjWCf5RZ1Ek/WCbxnZbaB1I/AAAAAAAAgZk/kH9IBYXFRJI-XA2E3BoVoHiPA9rCfIkvQCLcB/s640/201611%25E6%259C%2588%25E2%2597%2586%25E6%259D%25B1%25E4%25BA%25AC_8284.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">酒都很好喝,甜點也很棒!一杯日幣 900 元左右</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-1Cg47Ee3g10/WCbx2S9bsxI/AAAAAAAAgZs/ibyP2w8JuiIXM7wvED0qNpXPJ6wgNp0DwCLcB/s1600/201611%25E6%259C%2588%25E2%2597%2586%25E6%259D%25B1%25E4%25BA%25AC_9005.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="360" src="https://1.bp.blogspot.com/-1Cg47Ee3g10/WCbx2S9bsxI/AAAAAAAAgZs/ibyP2w8JuiIXM7wvED0qNpXPJ6wgNp0DwCLcB/s640/201611%25E6%259C%2588%25E2%2597%2586%25E6%259D%25B1%25E4%25BA%25AC_9005.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">甜點我最喜歡那個司康 (Scone)</td></tr>
</tbody></table>
裝潢很講究,潮的程度瞬間升了<span style="background-color: #fff2cc;">百分之兩百</span>。連菜單都不一樣,甜點跟飲料好吃(喝)到讓人讚不絕口,不過當然,價格也是相當地不一樣......<br />
<br />
至於經過好幾次說要喝的 Blue Bottle,路過的時候就想說晚點會來喝,晚點再拍就好,最後卻因為要大採買跟去一些沒去過的地方,於是就跟想買的雪肌粹洗面乳一樣忘記了......只好留待下次再訪東京時再喝吧。往好處想,不然我一個老宅宅實在真的不太知道我到東京要幹嘛了,而且現在買這種五千多塊台幣的廉航,價錢都快比來回高雄高鐵還便宜時,就真的好像只是在家裡附近旅遊而已......<br />
<br />
雖然說對一個老宅宅來說,每天窩在被窩裡就是一種幸福了。<br />
<br />
結尾前簡單總結一下在日本的這幾天生活,早上就是工作,中午或晚上就跟前同事或老姊及姊夫出去吃好料的或是買回家自己煮,然後外加熬夜寫 code 或玩桌遊,不過好像也因為走路走得比較多,體重也就沒有恐怖地直線上升。挑幾張照片紀錄一下這兩個禮拜的生活,避免記憶力不好的我全部忘光光。<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-siRlFcWmag4/WCb2Qe8HwuI/AAAAAAAAgbA/1zytw4vpKowesxLR2SsLT4xR1EdU7WgSgCEw/s1600/20161101_121925.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="360" src="https://1.bp.blogspot.com/-siRlFcWmag4/WCb2Qe8HwuI/AAAAAAAAgbA/1zytw4vpKowesxLR2SsLT4xR1EdU7WgSgCEw/s640/20161101_121925.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">到日本的第一餐是明太子可以吃到飽的炸雞套餐</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://2.bp.blogspot.com/-rSUXRJjoenk/WCb2UwrT_lI/AAAAAAAAgbE/5_Xtp1eOs7MwXiLjbcpP_zL5y0yszDb9ACEw/s1600/20161102_142410_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="360" src="https://2.bp.blogspot.com/-rSUXRJjoenk/WCb2UwrT_lI/AAAAAAAAgbE/5_Xtp1eOs7MwXiLjbcpP_zL5y0yszDb9ACEw/s640/20161102_142410_HDR.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">請老同事帶我參觀前東家日本東京的趨勢科技總部</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-bcPIQet3u24/WCe8bNgIg3I/AAAAAAAAgb4/oDBGRHlcv2Y0n08bhRddh00lDHI0FayoACLcB/s1600/20161103_191945.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://3.bp.blogspot.com/-bcPIQet3u24/WCe8bNgIg3I/AAAAAAAAgb4/oDBGRHlcv2Y0n08bhRddh00lDHI0FayoACLcB/s640/20161103_191945.jpg" width="360" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Wally 帶我去吃的立食牛排 (雖然店很大都是坐著),搭配芥末吃別有一番風味</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-j42X33tBhTA/WCb11mtfPUI/AAAAAAAAgag/ajSt5h80NxMprpX-0feLkYd-_3A3HYs3QCEw/s1600/20161105_134406.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="360" src="https://3.bp.blogspot.com/-j42X33tBhTA/WCb11mtfPUI/AAAAAAAAgag/ajSt5h80NxMprpX-0feLkYd-_3A3HYs3QCEw/s640/20161105_134406.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">在新宿吃的好吃牛舌套餐,兩千多日幣,真的好吃!</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://2.bp.blogspot.com/-4fBvieWYfic/WCb11c39gII/AAAAAAAAgaU/o-Cc4fmHc8YZ_CY7MV_SCsqtV18HkHEEgCEw/s1600/20161104_200843.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://2.bp.blogspot.com/-4fBvieWYfic/WCb11c39gII/AAAAAAAAgaU/o-Cc4fmHc8YZ_CY7MV_SCsqtV18HkHEEgCEw/s640/20161104_200843.jpg" width="360" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">蠻貴的握壽司......</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://2.bp.blogspot.com/-net5FUWdjms/WCb2QUlGuJI/AAAAAAAAga8/q1EzsIdHTyEZvZ5A6LxqlNuucqTArIF9gCEw/s1600/20161109_133605.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://2.bp.blogspot.com/-net5FUWdjms/WCb2QUlGuJI/AAAAAAAAga8/q1EzsIdHTyEZvZ5A6LxqlNuucqTArIF9gCEw/s640/20161109_133605.jpg" width="360" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">第一次在日本吃大阪燒跟文字燒,很多餐廳中午去吃便宜很多</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://2.bp.blogspot.com/-bIxuRcGSj6w/WCb12RrUqRI/AAAAAAAAgao/dE-ZpObhksoEZ3s8Lh84RFTWhSFo_4AmgCEw/s1600/20161105_193601.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="360" src="https://2.bp.blogspot.com/-bIxuRcGSj6w/WCb12RrUqRI/AAAAAAAAgao/dE-ZpObhksoEZ3s8Lh84RFTWhSFo_4AmgCEw/s640/20161105_193601.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">去超市買生魚片跟高級魚回來自己煎,順便配瓶啤酒</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><img border="0" height="640" src="https://3.bp.blogspot.com/-qM2CbxZ5_Qc/WCb4ZZGwFpI/AAAAAAAAgbQ/ovXitruPIc0rMPsIcFZ1vR55Qc3ujFmLQCLcB/s640/20161110_113653.jpg" style="margin-left: auto; margin-right: auto;" width="360" /></td></tr>
<tr><td class="tr-caption" style="text-align: center;">機場買漢堡當午餐等飛機</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-CtkmG5s28g8/WCb4ZZ-SCKI/AAAAAAAAgbM/isY8FiUVwLAjC9OUhLhRn6G-3Kv7CYQqACEw/s1600/20161110_121559.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://3.bp.blogspot.com/-CtkmG5s28g8/WCb4ZZ-SCKI/AAAAAAAAgbM/isY8FiUVwLAjC9OUhLhRn6G-3Kv7CYQqACEw/s640/20161110_121559.jpg" width="360" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">還遇到觀光局填問卷最後有送小禮物壽司橡皮擦</td></tr>
</tbody></table>
對了,在回來台灣前,靠著跟同事們一起的努力,順利地把第一版不完美但堪用、採用 WebSocket 的新聊天系統上線了 (這次是把主要功能全都翻新),有興趣的人可以來玩玩看!<br />
<br />
或是,可以丟履歷來當我的好同事!<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://2.bp.blogspot.com/-u0kw7kmdkDo/WCbzmby-u3I/AAAAAAAAgZ0/AVP9hpRMvVM1GXDtT4JgEx--seq4UMr8ACLcB/s1600/Screen%2BShot%2B2016-11-12%2Bat%2B6.46.58%2BPM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://2.bp.blogspot.com/-u0kw7kmdkDo/WCbzmby-u3I/AAAAAAAAgZ0/AVP9hpRMvVM1GXDtT4JgEx--seq4UMr8ACLcB/s640/Screen%2BShot%2B2016-11-12%2Bat%2B6.46.58%2BPM.png" width="358" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">https://m.mig.me/chat 目前只接受 mobile 訪問</td></tr>
</tbody></table>
感謝所有人讓我完成我的任性小旅行,也期待遠端工作的日漸普及。
Unknownnoreply@blogger.comShinagawa, Tokyo, Japan35.620132129722876 139.7284650323242735.607224629722879 139.70829503232426 35.633039629722873 139.74863503232427tag:blogger.com,1999:blog-4783512064634308801.post-13009666386577506412016-08-01T20:42:00.002+08:002020-07-09T12:33:33.541+08:00[ReactJS] [Redux] 改變 state 要寫在 action creator 裡還是 reducer 裡?<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-UYQlKUahVVk/V59HEXUDjoI/AAAAAAAAeaE/K96dsSL8_QYyudZ7u7BdvvTzm7euACvQwCLcB/s1600/redux.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://1.bp.blogspot.com/-UYQlKUahVVk/V59HEXUDjoI/AAAAAAAAeaE/K96dsSL8_QYyudZ7u7BdvvTzm7euACvQwCLcB/s1600/redux.png" /></a></div>
<br />
<br />
雖然從<a href="https://www.facebook.com/photo.php?fbid=10203261790485796&set=a.2095929118063.159852.1240391098&type=3&theater" target="_blank">兩年前</a>就知道 React 了,但是直到最近這兩個月才真的有機會把它用在 production 上,忙碌的寫 code 人生中也學到了一些有趣的東西。上禮拜有幾個值得記錄下來避免忘記的討論,其中我覺得最重要的是一個是:「<b><u>改變 state 要寫在 action creator 裡還是 reducer 裡?</u></b>」,所以在很久沒寫網誌的情況下,還是努力對抗懶惰蟲給寫完了,希望各位先進前輩指導交流。<br />
<br />
先提一下我們基本的 stack 是 ReactJS + Redux + redux-saga,所以下面的範例也是以這樣的基礎上敘述,同時避免文章落落長導致結論沒人看,先說我們最後的結論是<br />
<blockquote class="tr_bq">
<b>reducer 負責 state 的變化,如果有牽扯到 async 的 API 呼叫 (side effects),則是在 redux-saga 這層裡面處理。</b></blockquote>
<br />
<a name='more'></a>根據我們最後討論出來的東西如果寫成程式大概會長這樣:<br />
<br />
<script src="https://gist.github.com/andretw/3d4d0f4edc7f48990c5a1396908c766d.js"></script>那如果不是將改變 state 的邏輯寫在 reducer 裡的差別會在哪呢?在一些 Open Source 的 repo 裡我們有看到一些如下面範例的寫法,將改變 state 的邏輯寫在 action creator 裡,然後 reducer 大都只需要原封不動的將值取出來然後改變 store 裡的 state,Redux 的作者認為這樣是一種 anti-pattern 的寫法。<br />
<br />
<script src="https://gist.github.com/andretw/2643f41f37a47d49306ba9ab65bc7326.js"></script>
不過結論其實很簡單,因為 Redux 的<a href="http://redux.js.org/docs/basics/Reducers.html" target="_blank">官方文件第一段</a>就說了:<br />
<blockquote class="tr_bq">
Actions describe the fact that something happened, but <b>don’t specify how the application’s state changes in response</b>. <b><span style="color: red;">This is the job of a reducer</span></b>.</blockquote>
<br />
<h4>
參考來源:</h4>
<a href="https://gist.github.com/kof/9ead8b0899e2e1306311#gistcomment-1678816">https://gist.github.com/kof/9ead8b0899e2e1306311#gistcomment-1678816</a><br />
<a href="https://gist.github.com/kof/9ead8b0899e2e1306311#gistcomment-1690390">https://gist.github.com/kof/9ead8b0899e2e1306311#gistcomment-1690390</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-g91hVGobtOo/V57LB5jMYpI/AAAAAAAAeZ0/L0_zwlHOp-s7XvEuH_OZjz5QenQbIBTDwCLcB/s1600/reactjs-redux-change-state-in-action-creator-or-reducer-01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="290" src="https://2.bp.blogspot.com/-g91hVGobtOo/V57LB5jMYpI/AAAAAAAAeZ0/L0_zwlHOp-s7XvEuH_OZjz5QenQbIBTDwCLcB/s640/reactjs-redux-change-state-in-action-creator-or-reducer-01.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-bWM86Ualy40/V57LB3fQrgI/AAAAAAAAeZw/M_2LiOuLe9oCj5lkqjN6WQtCYVmvGLEXwCLcB/s1600/reactjs-redux-change-state-in-action-creator-or-reducer-02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="145" src="https://4.bp.blogspot.com/-bWM86Ualy40/V57LB3fQrgI/AAAAAAAAeZw/M_2LiOuLe9oCj5lkqjN6WQtCYVmvGLEXwCLcB/s640/reactjs-redux-change-state-in-action-creator-or-reducer-02.png" width="640" /></a></div>
<br />
<br />
<h4>
同場加映:</h4>
<b>action 的參數要多一層 payload 嗎?</b>答案是要,根據 <a href="https://github.com/acdlite/flux-standard-action" target="_blank">FSA</a> (Flux Standard Action) 來說是要的,好處是在取得 payload 上有一致性,也不用擔心有新手工程師會在 payload 裡面放了一個叫 type 的 attribute,結果把重要的 action type 給 override 了......Unknownnoreply@blogger.comtag:blogger.com,1999:blog-4783512064634308801.post-22217187119302740022016-04-15T23:35:00.003+08:002016-04-16T10:03:18.195+08:00如何在程式化腳本 (shell script) 內忽略異常錯誤結束 (exit(1))<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-UQnCYy0ymDU/VxEIjuyAKhI/AAAAAAAAchQ/Fq3ekIecJcUol8oztT-eMnJM_bNFAIbLQCK4B/s1600/how-to-ignore-exit-1-unexpected-exit-in-script.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://2.bp.blogspot.com/-UQnCYy0ymDU/VxEIjuyAKhI/AAAAAAAAchQ/Fq3ekIecJcUol8oztT-eMnJM_bNFAIbLQCK4B/s400/how-to-ignore-exit-1-unexpected-exit-in-script.png" width="311" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">快快樂樂學 shell scripts</td></tr>
</tbody></table>
最近在試著改善及整合公司其中一個專案的多國語系 (I18N) 自動化流程 (沒錯,又是熟悉的 I18N 好朋友)。除了根據現有的開發流程進行客製化的設計外,一路從開發、驗證、上線,每一個環節都需要考慮到流暢度與困難點,所幸有一些先前的小經驗,不過最後還是整整花了相當充實的三天半左右才完工。<br />
<br />
在撰寫自動化流程腳本時遇到了一個有趣的小問題,解完後我覺得這問題雖然小卻也挺有意思的。於是我隔天就提出來跟公司的同事們一起討論,在產生了一些腦力激盪的小火花後,決定花點時間把問題和解法寫出來,一方面替很久沒寫的網誌灌灌水,另一方面則是希望拋出了這塊小磚後,會有一些不一樣,甚至更好、更有趣的大玉會冒出來一起討論。<br />
<br />
<h4>
問題</h4>
<blockquote class="tr_bq">
有一個 shell script 裡面執行了三個指令:<br />
<ol>
<li>git add .</li>
<li>git commit -m "blahblahblah"</li>
<li>git push</li>
</ol>
唯一的條件是:這個 shell script 不允許有任何的異常錯誤發生,因為有異常錯誤發生會中斷這個 shell script,也就是在運行指令時都必須要是 exit(0) 才可以。所以也可以想成 shell script 是長這樣:</blockquote>
<blockquote class="tr_bq">
function run_cmd(){<br />
git add .<br />
git commit -m "blahblahblah"<br />
git push<br />
}<br />
run_cmd()<br />
ret=$?<br />
if [ $ret -gt 0 ]; then<br />
echo "Error!"<br />
fi </blockquote>
<br />
所以問題點在哪?<br />
<br />
假設這個 script 在執行過 1. git add . 後,repo 裡並沒有任何檔案有被更改,正常來說,在執行 2. git commit -m "blahblahblah" 時 git 就會丟出類似下面這樣的訊息:<br />
<blockquote class="tr_bq">
On branch master<br />
Your branch is up-to-date with 'migme/master'.<br />
nothing to commit, working directory clean</blockquote>
因為 git 發現沒有檔案可以 commit 後拋出了 exit(1) 異常結束 (可以用 echo $? 查看得知),最後進而導致 script 接到錯誤產生也異常結束。<br />
<br />
於是,要怎樣忽略掉 git 所拋出的異常錯誤,讓後續的指令能夠順利執行呢?<br />
<br />
最後大概有兩種比較短的解法:<br />
<ol>
<li>用 pipe:<br />git commit -m "blahblah" | cat</li>
<li>用 true:<br />git commit -m "blahblah" || true</li>
</ol>
<br />
這兩種都可以忽略掉 exit(1) 產生時的異常錯誤,不過這兩種方法所表示的意義有些不同,就讓客倌您自己細細品嚐跟探討了。<br />
<br />
<br />Unknownnoreply@blogger.comtag:blogger.com,1999:blog-4783512064634308801.post-42368075946520297502015-10-17T18:07:00.000+08:002016-04-09T16:04:10.311+08:00用 Charles Proxy 編修前端程式 (JavaScript, CSS, Images, etc) 而不用去碰後端程式年初加入了一個在東南亞頗具知名度,但在台灣卻沒啥人知道的社群網站公司 -- <a href="https://mig.me/" target="_blank">migme</a>。目前擁有逾九千萬使用者、月活躍使用者數 (MAU) 大於兩千四百萬的 <a href="https://mig.me/" target="_blank">migme</a>,後端 (Backend) 程式經過多年的演化後可謂極其複雜,不僅選用的程式語言相當廣泛,裡頭的商業邏輯與需要相容的平台很容易就可以讓一位有經驗的程式設計師感到挫折。(我們持續有在徵才,總部目前設在新加坡,年假起跳 20 天喔,歡迎一起來玩,啾咪 >_^ )<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://i.imgur.com/XxiYRya.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://i.imgur.com/XxiYRya.png" height="402" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">@Credit: <a href="https://www.facebook.com/devbattles?fref=photo" target="_blank">DevBattles</a> 不知不覺中我們可能養了一隻很大的怪獸</td></tr>
</tbody></table>
儘管我們已經用了 <a href="https://www.vagrantup.com/" target="_blank">Vagrant</a> (嗯,請不要問為什麼沒用 Docker,因為 Vagrant 是在 Docker 之前最紅的),努力整合所有的服務 (services) 到 Vagrant 的映像檔 (Image) 裡,試著減低捱過新手村的門檻,但是偶爾還是會因為像是某個 Library 版本不相容,或系統版本沒更新等等一些雜七雜八的事情,躲藏在暗處的小惡魔就會偷偷出來咬一口,這一口通常可大可小,一旦出現,可就會讓前端 (Frontend) 工程師或新加入的同事,耗掉一個下午或一整天時間來除這些可能跟前端完全沒關係的蟲了。<br />
<br />
也就因為這樣,使我們依舊把成功執行開發環境視為一種成就,也是證明自己從超新手進階到新手的第一個獎盃。<br />
<br />
那麼,該怎麼解決前端工程師的痛呢?<br />
<br />
<a name='more'></a><br />
這時候 <a href="http://www.charlesproxy.com/" target="_blank">Charles Proxy</a> (或 Charles) 就可以派上用場了。<br />
<br />
<h4>
目標</h4>
<div>
<br /></div>
<blockquote class="tr_bq">
基本的概念就是<u><b>用瀏覽器連上相對穩定的遠端測試網站</b></u> (Alpha、Beta、Staging,甚至可以是 Production,通常是要拿來做 Integration Test 用的),接著<b><u>利用 <a href="http://www.charlesproxy.com/" target="_blank">Charles Proxy</a> 將想要更改的 JavaScript (、CSS、Assets) 檔案,強迫指定使用本地端 (Map Local) 的檔案</u></b>。這樣一來,就可以達到只想更改前端程式,而完全不用理後端程式。</blockquote>
<br />
<h4>
執行步驟</h4>
<div>
<br /></div>
<ol>
<li>前往 <a href="http://www.charlesproxy.com/" target="_blank">Charles Proxy</a> 下載程式</li>
<li>安裝 (以下為 Mac OS X截圖)</li>
<li>執行程式後會看到如下的 <a href="http://www.charlesproxy.com/" target="_blank">Charles Proxy</a> 使用介面<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-GDqeaB9WQw0/ViIUTdsft6I/AAAAAAAAYwo/wEmzsN8zz2U/s1600/charles_proxy_map_local_002.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="387" src="https://1.bp.blogspot.com/-GDqeaB9WQw0/ViIUTdsft6I/AAAAAAAAYwo/wEmzsN8zz2U/s640/charles_proxy_map_local_002.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">開啟時會預設開啟一個 session 開始接收所有的網路流量封包</td></tr>
</tbody></table>
</li>
<li>點擊上方 Tools -> Map Local...<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-ca5Be8f0KJ4/ViIUTY16TZI/AAAAAAAAYww/zPehbWZUokM/s1600/charles_proxy_map_local_003.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://1.bp.blogspot.com/-ca5Be8f0KJ4/ViIUTY16TZI/AAAAAAAAYww/zPehbWZUokM/s640/charles_proxy_map_local_003.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Map Local 是將所接收到的檔案映射到本機端 (Local)</td></tr>
</tbody></table>
</li>
<li>點擊之後出現對話框,點選 Add 進行新增映射<br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-t9YP1yQENxw/ViIUT9MUx8I/AAAAAAAAYw8/dmSKK7WwHAE/s1600/charles_proxy_map_local_004.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://1.bp.blogspot.com/-t9YP1yQENxw/ViIUT9MUx8I/AAAAAAAAYw8/dmSKK7WwHAE/s640/charles_proxy_map_local_004.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">目前映射設定</td></tr>
</tbody></table>
</li>
<li>可以透過左邊的 Structure 或 Sequence 搭配上 filter 功能找尋欲取代的目標檔案<br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-VtdIIr5oxss/ViIUUoF-CxI/AAAAAAAAYxI/fMpWYJf5Fzw/s1600/charles_proxy_map_local_005.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://4.bp.blogspot.com/-VtdIIr5oxss/ViIUUoF-CxI/AAAAAAAAYxI/fMpWYJf5Fzw/s640/charles_proxy_map_local_005.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">可以將網址直接貼在 Host 的欄位,Charles Proxy 會自動分類</td></tr>
</tbody></table>
</li>
<li>滑鼠游標 (cursor) 動一下到別的欄位<br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-JY3LSX4MGFM/ViIUVAlb-hI/AAAAAAAAYxM/9pDe3bzw5nI/s1600/charles_proxy_map_local_006.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://4.bp.blogspot.com/-JY3LSX4MGFM/ViIUVAlb-hI/AAAAAAAAYxM/9pDe3bzw5nI/s640/charles_proxy_map_local_006.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">將焦點 (focus) 移到別的地方之後,Charles Proxy 會自動將網址切好</td></tr>
</tbody></table>
</li>
<li>選取本機端 (Local) 欲置換遠端檔案的檔案 (好饒舌<br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-ZgqsHUin77I/ViIUVbbjJgI/AAAAAAAAYxQ/swJnro-V290/s1600/charles_proxy_map_local_007.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://3.bp.blogspot.com/-ZgqsHUin77I/ViIUVbbjJgI/AAAAAAAAYxQ/swJnro-V290/s640/charles_proxy_map_local_007.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">指定本機端 (Local) 取代檔案</td></tr>
</tbody></table>
</li>
<li>按下 OK 就完成了</li>
</ol>
<br />
<h4>
備註:</h4>
<a href="http://www.charlesproxy.com/" target="_blank">Charles Proxy</a> 如果沒有購買而是試用時蠻令人討厭的,只能用三十分鐘就要重開,然後開啟的時候還會故意延遲 (Delay) 個十幾秒才讓你進入主程式。<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-f7nJgvgR2Fs/ViIUTPdpZiI/AAAAAAAAYwk/J1h6RayvCUw/s1600/charles_proxy_map_local_001.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="183" src="https://3.bp.blogspot.com/-f7nJgvgR2Fs/ViIUTPdpZiI/AAAAAAAAYwk/J1h6RayvCUw/s400/charles_proxy_map_local_001.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: 12.8px;">團購有打折價格,我們是購買 10+ 的授權。</span></td></tr>
</tbody></table>
<br />
<br />Unknownnoreply@blogger.comtag:blogger.com,1999:blog-4783512064634308801.post-18469588215542681772015-09-12T23:43:00.003+08:002017-06-09T00:32:20.448+08:00[開箱] Panasonic RULO MC-RS1 使用心得與評價<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="http://2.bp.blogspot.com/-6rjBuseetzg/VfRBtgCeOrI/AAAAAAAAWN8/sOaJ43jiYAc/s1600/20150808_171644.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://2.bp.blogspot.com/-6rjBuseetzg/VfRBtgCeOrI/AAAAAAAAWN8/sOaJ43jiYAc/s640/20150808_171644.jpg" width="480" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 12.8px;">準備開箱,型號是 MC-RS1-W</td></tr>
</tbody></table>
上個月因為全家的心血來潮,在日本料理店慶祝完老爸的生日後,突然買了機票,決定一個禮拜後飛往日本東京家庭旅遊,先不說那時候才五個月大的小傢伙的護照問題,在連證件照都還沒拍、飯店都還沒著落就訂了機票這種衝動的事情,實在有種大學時代突然就夜衝的熟悉感。<br />
<br />
回到正題,由於這次去東京花了一筆不小的金額購買了一台<strike>小媳婦</strike>掃地機器人(折合台幣約兩萬三千元左右),在使用一個多月後,決定來分享一下使用心得,以便讓不知道該型號(Panasonic RULO MC-RS1)優缺點的朋友有個參考依據。<br />
<br />
<blockquote class="tr_bq">
註:由於購買時沒有比價又趕時間,在秋葉原 <a href="http://www.yodobashi.com/" target="_blank">Yodobashi</a> 買到的價錢比之後亂逛 <a href="http://kakaku.com/" target="_blank">價格.com</a> 查到的<b>含稅</b>價格貴了大約一萬五千元日幣左右,所以如果沒有未稅的話,大約被貴了兩萬元日幣,之後我應該不會再到 Yodobashi 買電器了......
</blockquote>
<a name='more'></a><div id="fb-root">
</div>
<script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v2.3"; fjs.parentNode.insertBefore(js, fjs);}(document, 'script', 'facebook-jssdk'));</script><br />
<div class="fb-post" data-href="https://www.facebook.com/andretw/posts/10204770792689908" data-width="500">
<div class="fb-xfbml-parse-ignore">
<blockquote cite="https://www.facebook.com/andretw/posts/10204770792689908">
昨天吃完超貴的日本料理後,今天全家就訂好了下禮拜去日本的機票,有沒有這麼熱血的啊,不是,是有沒有這麼想亂花錢的啊~~~ (狀態顯示前一個禮拜才訂就註定要被當盤子中)<br />
Posted by <a href="https://www.facebook.com/andretw">Andre Lee</a> on <a href="https://www.facebook.com/andretw/posts/10204770792689908">Monday, 20 July 2015</a></blockquote>
</div>
</div>
<br />
<br />
在購買之前,我本來是想要購買 LG 的掃地機器人,雖然在那時只有搜尋到 <a href="http://www.486word.com/weekly_page.php?id=QD48PyomJTIwMkAoKyMlXis=" target="_blank"><b>486</b></a> 的心得文,雖然他給的評價不高,但是我覺得她的樣子很特別,所以最後還是決定買她了。<br />
<br />
不過雖然 486 給的評價不高,但是這篇名為「<a href="http://www.insertmag.ca/2015/03/panasonic-mc-rs1-rulo/" target="_blank">最強清潔機器人:Panasonic MC-RS1 Rulo</a>」的<strike>業配</strike>文章看起來倒是挺吸引人的。<br />
<br />
廢話不多說,開始開箱了:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-VBH9NYClVjI/VfRBtrtz5EI/AAAAAAAAWOI/tIvrHJ_vbcs/s1600/20150808_171719.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://4.bp.blogspot.com/-VBH9NYClVjI/VfRBtrtz5EI/AAAAAAAAWOI/tIvrHJ_vbcs/s640/20150808_171719.jpg" width="480" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">品質保證的日本製</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-sZ_-5Vh5WMM/VfRBtvhH3vI/AAAAAAAAWOY/rnd19hzfafw/s1600/20150808_171758.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://4.bp.blogspot.com/-sZ_-5Vh5WMM/VfRBtvhH3vI/AAAAAAAAWOY/rnd19hzfafw/s640/20150808_171758.jpg" width="480" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">配件不多,有遙控器、HOME、主機、電池、說明書跟保證書</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-hslMUCBKnfc/VfRBuXEHHBI/AAAAAAAAWOo/HRjy3HsLAgE/s1600/20150808_171948.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://4.bp.blogspot.com/-hslMUCBKnfc/VfRBuXEHHBI/AAAAAAAAWOo/HRjy3HsLAgE/s640/20150808_171948.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">拿出來排一排:遙控器、HOME、主機、電池、說明書跟保證書</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-PYkBXmd1A1Y/VfRBvpZeVBI/AAAAAAAAWPQ/dV6Y1-RGKxg/s1600/20150808_191101.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://2.bp.blogspot.com/-PYkBXmd1A1Y/VfRBvpZeVBI/AAAAAAAAWPQ/dV6Y1-RGKxg/s640/20150808_191101.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">小媳婦實際開始工作</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-ohX491e9_sc/VfRBv_6P0yI/AAAAAAAAWOw/01OUFaho6jc/s1600/20150808_191202.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://1.bp.blogspot.com/-ohX491e9_sc/VfRBv_6P0yI/AAAAAAAAWOw/01OUFaho6jc/s640/20150808_191202.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">連 costco 買的軟地毯也可以爬上去幫忙吸</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-dv1libJczaU/VfRBvbE_LBI/AAAAAAAAWPM/bcKoVvQTDfg/s1600/20150808_190956.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://1.bp.blogspot.com/-dv1libJczaU/VfRBvbE_LBI/AAAAAAAAWPM/bcKoVvQTDfg/s640/20150808_190956.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">沙發底下應該算是她的強項</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-1DlSIxYZ-ds/VfRBxJTJPmI/AAAAAAAAWPI/bBSBigkOB2U/s1600/20150822_193211.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://3.bp.blogspot.com/-1DlSIxYZ-ds/VfRBxJTJPmI/AAAAAAAAWPI/bBSBigkOB2U/s640/20150822_193211.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">雖然有時候他會笨笨的被困住然後用日語求救</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-RQkWW0-1doU/VfRBwmtAtCI/AAAAAAAAWPE/h7DNs4qH18E/s1600/20150808_201341.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://1.bp.blogspot.com/-RQkWW0-1doU/VfRBwmtAtCI/AAAAAAAAWPE/h7DNs4qH18E/s640/20150808_201341.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">集塵室雖然可能有點小,但是我覺得還算夠用,而且清出來的灰塵很細,吸得應該很乾淨</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-uc_uOm0N2Gs/VfRBwxeWejI/AAAAAAAAWPA/tAAfxMUoNp4/s1600/20150808_221956.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://3.bp.blogspot.com/-uc_uOm0N2Gs/VfRBwxeWejI/AAAAAAAAWPA/tAAfxMUoNp4/s640/20150808_221956.jpg" width="480" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">第一次工作就幫我姐找到了她的耳環</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-y5sQR-6JQ30/VfRBvBjWfeI/AAAAAAAAWOc/kz6ZL22WqAU/s1600/20150808_172238.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://1.bp.blogspot.com/-y5sQR-6JQ30/VfRBvBjWfeI/AAAAAAAAWOc/kz6ZL22WqAU/s640/20150808_172238.jpg" width="480" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">做完工作她會自己回家</td></tr>
</tbody></table>
<b>心得:</b><br />
<br />
<ul>
<li>集塵室小,但是夠用</li>
<li>聲音比 iRobot 小</li>
<li>吸過之後的地板蠻乾淨的</li>
<li>可以設定每日定期工作,點選設定時只有 0-9 可以選擇,意思是距離現在的幾小時後的那個時間每天都要工作,假設現在是下午兩點,你選擇並設定了 3 之後,小媳婦就會每天下午五點出來工作</li>
<li>地上的東西要收好,不然她有時候會被線纏住而停止工作</li>
<li>外型蠻可愛的我喜歡</li>
</ul>
<div>
<br /></div>
<div>
<b>2016/06/13 後註:</b></div>
<div>
<b><br /></b></div>
<div>
最近因為 Panasonic RULO MC-RS1 在台灣終於上市了 (日本的新款 MC-RS200 都出了...),導致這篇文章突然流量大增,所以補一些用了近一年的心得在這邊。</div>
<div>
這台小媳婦很愛玩線,把我一條新買的蘋果電源線給捲壞了 (兩千多塊才剛買的電源線啊!),所以從此之後,我有點不太敢把我很貴的線放在地上了。<br />
<br />
上禮拜我有請我姐從日本買回來耗材,含左右蟑螂毛加上全新集塵室大約五千日圓左右,。</div>
<div>
<br /></div>
<div>
除了日文講什麼東西我有點聽不懂以及我兒子很愛欺負她以外,這台我用得覺得蠻不錯的,只不過家人最近有買 <a href="https://tw.partner.buy.yahoo.com/gd/buy?mcode=MV83VXdPNUpyeG9DeDhTU0xUTDBibWM1YXUvaG5IRU55M2dDdHptRmxDcHNRPQ==&url=https%3A%2F%2Ftw.buy.yahoo.com%2Fgdsale%2FLG%25E6%25A8%2582%25E9%2587%2591-%25E9%258A%2580%25E7%2581%25B0%25E8%2589%25B2%25E6%258E%2583%25E5%259C%25B0%25E6%25A9%259F%25E5%2599%25A8%25E4%25BA%25BA-VR65715LVM-6608926.html" target="_blank">LG 新一代的掃地機器人</a>,聲音聽起來感覺比我的小媳婦還小,上面還特別標榜不會捲線,實在讓我著實有心動了一下,只是我的機器人還買不夠久,未屆除役年齡,她只好繼續苦命地工作下去了。<br />
<br />
<br /></div>
<div style="display: inline-block; margin-bottom: 10px; margin-left: 10px; margin-right: 5px; max-height: 160px; min-height: 160px; width: 224px;">
<div style="float: left;">
<a href="http://www.momoshop.com.tw/goods/GoodsDetail.jsp?osm=league&i_code=4380254&memid=6000009672&cid=apuad&oid=2"><img src="//www.momoshop.com.tw/goodsimg/0004/380/254/4380254_L.jpg" style="width: 80px;" /></a></div>
<div style="color: #333333; float: left; font-size: 14px; line-height: 18px; margin-left: 15px; padding-top: 5px; text-align: left; width: 129px;">
<div style="margin: 0px;">
<a href="http://www.momoshop.com.tw/goods/GoodsDetail.jsp?osm=league&i_code=4380254&memid=6000009672&cid=apuad&oid=2">【三星】POWERbot極勁氣旋機器人VR20H9050UW/TW(VR20H9050UW/TW)</a></div>
<div style="margin: 0px;">
<input onclick="window.location.href='http://www.momoshop.com.tw/goods/GoodsDetail.jsp?osm=league&i_code=4380254&memid=6000009672&cid=apuad&oid=2'" type="button" value="我要購買" /></div>
</div>
</div>
<div style="display: inline-block; margin-bottom: 10px; margin-left: 10px; margin-right: 5px; max-height: 160px; min-height: 160px; width: 224px;">
<div style="float: left;">
<a href="http://www.momoshop.com.tw/goods/GoodsDetail.jsp?osm=league&i_code=4480978&cid=apuad&oid=1&memid=6000009672"><img src="//www.momoshop.com.tw/goodsimg/0004/480/978/4480978_L.jpg" style="width: 80px;" /></a></div>
<div style="color: #333333; float: left; font-size: 14px; line-height: 18px; margin-left: 15px; padding-top: 5px; text-align: left; width: 129px;">
<div style="margin: 0px;">
<a href="http://www.momoshop.com.tw/goods/GoodsDetail.jsp?osm=league&i_code=4480978&cid=apuad&oid=1&memid=6000009672">【Panasonic 國際牌】RULO 原創三角形掃地機器人(MC-RS1T-W)-獨家送【小太陽】1.8L不鏽鋼快煮壺(TE-180)</a></div>
<div style="margin: 0px;">
<input onclick="window.location.href='http://www.momoshop.com.tw/goods/GoodsDetail.jsp?osm=league&i_code=4480978&cid=apuad&oid=1&memid=6000009672;cid=apuad&oid=2'" type="button" value="我要購買" /></div>
</div>
</div>
<br />
<div style="display: inline-block; margin-bottom: 10px; margin-left: 10px; margin-right: 5px; max-height: 160px; min-height: 160px; width: 224px;">
<div style="float: left;">
<a href="http://www.momoshop.com.tw/goods/GoodsDetail.jsp?osm=league&i_code=3159188&memid=6000009672&cid=apuad&oid=2"><img src="//www.momoshop.com.tw/goodsimg/0003/159/188/3159188_L.jpg" style="width: 80px;" /></a></div>
<div style="color: #333333; float: left; font-size: 14px; line-height: 18px; margin-left: 15px; padding-top: 5px; text-align: left; width: 129px;">
<div style="margin: 0px;">
<a href="http://www.momoshop.com.tw/goods/GoodsDetail.jsp?osm=league&i_code=3159188&memid=6000009672&cid=apuad&oid=2">【LG 樂金】雙眼小精靈 清潔掃地機器人(VR64702LVM)</a></div>
<div style="margin: 0px;">
<input onclick="window.location.href='http://www.momoshop.com.tw/goods/GoodsDetail.jsp?osm=league&i_code=3159188&memid=6000009672&cid=apuad&oid=2'" type="button" value="我要購買" /></div>
</div>
</div>
<div style="display: inline-block; margin-bottom: 10px; margin-left: 10px; margin-right: 5px; max-height: 160px; min-height: 160px; width: 224px;">
<div style="float: left;">
<a href="http://www.momoshop.com.tw/goods/GoodsDetail.jsp?osm=league&i_code=4325100&memid=6000009672&cid=apuad&oid=2"><img src="//www.momoshop.com.tw/goodsimg/0004/325/100/4325100_L.jpg" style="width: 80px;" /></a></div>
<div style="color: #333333; float: left; font-size: 14px; line-height: 18px; margin-left: 15px; padding-top: 5px; text-align: left; width: 129px;">
<div style="margin: 0px; max-height: 160px; min-height: 160px;">
<a href="http://www.momoshop.com.tw/goods/GoodsDetail.jsp?osm=league&i_code=4325100&memid=6000009672&cid=apuad&oid=2">【LG 樂金】新一代變頻掃地機器人VR65713LVM(櫻桃紅)</a></div>
<div style="margin: 0px;">
<input onclick="window.location.href='http://www.momoshop.com.tw/goods/GoodsDetail.jsp?osm=league&i_code=4325100&memid=6000009672&cid=apuad&oid=2'" type="button" value="我要購買" /></div>
</div>
</div>
<br />Unknownnoreply@blogger.comtag:blogger.com,1999:blog-4783512064634308801.post-79076659385326688122015-02-05T15:19:00.001+08:002017-06-03T21:49:15.313+08:00[MySQL] information_schema 中 USER_PRIVILEGES 沒有 'root'@'localhost'<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-N0szp4sirNc/VNMWesGu3UI/AAAAAAAAD5k/fJSrg6JpuqA/s1600/how_to_recovery_your_mysql.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="422" src="//3.bp.blogspot.com/-N0szp4sirNc/VNMWesGu3UI/AAAAAAAAD5k/fJSrg6JpuqA/s1600/how_to_recovery_your_mysql.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">正常情況的 USER_PRIVILEGES 表格 (table)</td></tr>
</tbody></table>
因為自己的電腦裡面有兩個 mysqld, 為了看起來漂亮, 也可以用 alfred 快速開啟想要測試的東西, 我決定留下 <a href="http://www.mamp.info/en/" target="_blank">MAMP</a> 包的 MySQL, 但是可能因為之前亂更新或是做了什麼蠢事, 我的 USER_PRIVILEGES 裡面 竟然只剩下 ''@'localhost' 這樣奇怪的帳號, 於是我想做什麼事情都會被系統說權限不足。<br />
<a name='more'></a><br />
經過大約三十分鐘左右我才解決了這個問題, 所以留下一點小記錄, 以備不時之需。<br />
<ol>
<li>先停止 mysqld</li>
<li>執行 mysqld --skip-grant-tables</li>
<li>在 MySQL shell 裡面執行下面三個指令:</li>
<ol>
<li>UPDATE mysql.user SET Grant_priv='Y', Super_priv='Y' WHERE User='root';</li>
<li>FLUSH PRIVILEGES;</li>
<li>GRANT ALL ON *.* TO 'root'@'localhost';</li>
</ol>
</ol>
<div>
大概就是這樣, 主要就是利用先略過權限的表格, 然後登入之後進行更新。<br />
<br />
打完收工, 騙一篇好久沒更新的網誌。</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-36714019998561987522014-09-21T23:38:00.001+08:002017-05-31T11:54:22.764+08:00[PyCon JP] 2014 日本 PyCon 研討會隨記<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-R22b0y_aQCM/VB65yQLc5iI/AAAAAAAADsg/vn8XXYA7Ke4/s1600/pyconjp2014_speaking.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="//1.bp.blogspot.com/-R22b0y_aQCM/VB65yQLc5iI/AAAAAAAADsg/vn8XXYA7Ke4/s1600/pyconjp2014_speaking.jpg" height="360" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://sushiwens.blogspot.tw/" target="_blank">Sushi</a> 幫我拍的演講照片</td></tr>
</tbody></table>
<script async="" class="speakerdeck-embed" data-id="bff4be20203f013253ae5234a31dec8b" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script><br />
這次原本投稿兩個題目, 一個是 Mezzanine 的 i18n 機制和流程, 另一個則是條條好爛路的開發心路歷程,
最後沒想到條條好爛路的開發心路歷程被接受採用了, 於是突然間就要在超級忙碌的結婚、買房行程中臨時加入了一個到日本演講的小副本。<br />
<br />
因為結婚忙碌的關係, 直到要出發的那一個禮拜我才把機票跟住宿都給搞定, 選擇搭廉價航空跟膠囊旅館, 說實在的以現在快三十歲的年紀來說有些辛苦, 不過因為結婚跟買房的開銷壓力讓我不得不儘量選便宜的就好。<br />
<a name='more'></a><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-ogPW_oBH7H0/VB7aZy6-o2I/AAAAAAAADuA/gPMoqLrFxVQ/s1600/pyconjp2014_1980yen_hotel_counter.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="//2.bp.blogspot.com/-ogPW_oBH7H0/VB7aZy6-o2I/AAAAAAAADuA/gPMoqLrFxVQ/s1600/pyconjp2014_1980yen_hotel_counter.jpg" height="480" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">要自己投錢領券的櫃檯</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-hlrEMBNj41c/VB66fjIHXEI/AAAAAAAADsw/n39T-Y4BB6A/s1600/pyconjp2014_1980yen_hotel.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="//2.bp.blogspot.com/-hlrEMBNj41c/VB66fjIHXEI/AAAAAAAADsw/n39T-Y4BB6A/s1600/pyconjp2014_1980yen_hotel.jpg" height="640" width="480" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">有一個個人鞋櫃、置物櫃, 下面也是床鋪, 但是入口在另外一邊</td></tr>
</tbody></table>
廉價航空的部分我是搭香草的, 來回大約八千五百元台幣左右。至於住宿, 我是住在上野、入谷附近的膠囊旅館, 但是它不是傳統的膠囊旅館, 它比較像是青年旅館+膠囊旅館的綜合體, 挺新、挺不錯的, 每天原價是 1980 円, 因為適逢假日, 每天加價成 2180 円, 不能刷卡, 用投幣機結帳, 折合台幣約 630 元/晚。<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-EJ67hQJm_aM/VB67sRCmNbI/AAAAAAAADtE/XeW4TmonhQE/s1600/pyconjp2014_preparing.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="//2.bp.blogspot.com/-EJ67hQJm_aM/VB67sRCmNbI/AAAAAAAADtE/XeW4TmonhQE/s1600/pyconjp2014_preparing.jpg" height="480" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">準備投影片</td></tr>
</tbody></table>
PyCon JP 2014 的會場在東京台場的東京國際交流館, 搭乘百合海鷗線到「船の科学館」站下車後走幾分鐘就到了。由於我的演講在第一天下午, 有點緊張的我很早就到了會場外編修著投影片。<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-Hng5EFj3qto/VB69XtCvddI/AAAAAAAADtQ/1czbr_DmvCk/s1600/pyconjp2014_lineup.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="//2.bp.blogspot.com/-Hng5EFj3qto/VB69XtCvddI/AAAAAAAADtQ/1czbr_DmvCk/s1600/pyconjp2014_lineup.jpg" height="480" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">大約六百人的活動, 正逢日本三天連假還來參加10000円的自費研討會, 這樣的人數真的挺不錯的了 (尤其Python 在日本的開發者遠少於 Ruby 啊) </td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-QNbTj_T_uZg/VB669ByO4CI/AAAAAAAADs8/iugPzBswTPI/s1600/pyconjp2014_robot.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><span style="color: black;"><img border="0" src="//1.bp.blogspot.com/-QNbTj_T_uZg/VB669ByO4CI/AAAAAAAADs8/iugPzBswTPI/s1600/pyconjp2014_robot.jpg" height="640" width="480" /></span></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: small;">可程式化(programmable)的機器人, 最小的定價 20 幾萬台幣...</span></td></tr>
</tbody></table>
這次大會的主題是 Re-discover Python, 擔任 Keynote 的主講者是 Python Software Foundation 及 Heroku 的成員, 講題中說了許多比較 Python 2.7 和 3 的差別, 但在最後 Q&A 時說了一句"我不知道將 Python 2.7 升級到 3 的好處有什麼", 頓時替整個演說做了結尾, 是我對這 Keynote 印象最深的部分。<br />
<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-ay3UE-4i_kA/VB7gGGNgZ4I/AAAAAAAADug/mfw97lAEJBs/s1600/pyconjp2014_sharing.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="//3.bp.blogspot.com/-ay3UE-4i_kA/VB7gGGNgZ4I/AAAAAAAADug/mfw97lAEJBs/s1600/pyconjp2014_sharing.jpg" height="428" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">我對 Python 的評價還是覺得最強在資料處理的部分</td></tr>
</tbody></table>
<div>
第一天還算蠻順利的在全程英文演講後結束了, 講完後的 Q&A 時間有五、六個聽眾踴躍地提出問題, 想到有人這麼認真的聽, 就挺開心的, 尤其第一天的晚宴中更有幾位聽眾認出我來向我問問題, 可以把自己知道的東西跟那麼多人分享, 又有這麼多人有興趣, 著實讓人開心不已, 短短 30 分鐘演講, 讓第一次用英文演講的我收穫頗多。<br />
<br />
至於為什麼說還算"蠻"順利的, 因為唯一的失誤就在投影片提到 OpenShift 的三次中, 把最後一次的 OpenShift 打成 "OpenShit" (不過這可以證明我都是一個一個字手打的...), 天啊, 而且還剛好在 OpenShift 傳教士的前一個 session 有這種失誤, 實在有夠尷尬 XD, 不過也因為這個失誤, 讓我多了很多機會跟 Red Hat 來的傳教士 shekhargulati 聊了很多天。<br />
<blockquote class="twitter-tweet" lang="en">
What a coincidence! I misspelled "OpenShift" to "OpenShit" before the speaker <a href="https://twitter.com/hashtag/shekhargulati?src=hash">#shekhargulati</a> from OpenShift. I love OpenShift, I mean it. :p<br />
— Andre Lee (@chaotinglee) <a href="https://twitter.com/chaotinglee/status/510713424678903808">September 13, 2014</a></blockquote>
</div>
<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-NrZ3zVR2z1A/VB7a61ZKQcI/AAAAAAAADuI/iI2t6XrvR3Q/s1600/pyconjp2014_pynes.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="//2.bp.blogspot.com/-NrZ3zVR2z1A/VB7a61ZKQcI/AAAAAAAADuI/iI2t6XrvR3Q/s1600/pyconjp2014_pynes.jpg" height="480" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">PyNES</td></tr>
</tbody></table>
<div>
第二天講題裡面我比較有印象的是這個用 Python 轉換成 NES 任天堂遊戲的主題, 遠從巴西前來參加的講者。</div>
<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-8rvzo9wNQIQ/VB7Wx-oaDDI/AAAAAAAADto/sI-xpgNYko4/s1600/pyconjp2014_robot_drawing.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="//2.bp.blogspot.com/-8rvzo9wNQIQ/VB7Wx-oaDDI/AAAAAAAADto/sI-xpgNYko4/s1600/pyconjp2014_robot_drawing.jpg" height="480" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">閉幕式前的抽獎活動, 由機器人來抽, 我的號碼是20, 前後號都被抽到了, 哭哭, 我好想要那件小企鵝的衣服啊!</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-CFcYbMDcUxo/VB7YCM_uLrI/AAAAAAAADt0/YFk10Gm87Pw/s1600/pyconjp2014_closing.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="//4.bp.blogspot.com/-CFcYbMDcUxo/VB7YCM_uLrI/AAAAAAAADt0/YFk10Gm87Pw/s1600/pyconjp2014_closing.jpg" height="480" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">結束前工作人員合照(這次多虧Sushi跟GiGi的高人氣, 才有更多機會跟一堆人交流)</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-H48uvToHu1M/VB6-HciUqQI/AAAAAAAADtY/oEVej7wPkFo/s1600/pyconjp2014_after_party.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="//2.bp.blogspot.com/-H48uvToHu1M/VB6-HciUqQI/AAAAAAAADtY/oEVej7wPkFo/s1600/pyconjp2014_after_party.jpg" height="480" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">活動結束後專屬講者與志工要價不菲的 Well Done Party (After Party)</td></tr>
</tbody></table>
不論是第一天或第二天的 Well Done Party 都相當地有趣, 調酒和啤酒無限暢飲, 東西也很好吃, 還可以跟來自四面八方的朋友東扯西扯聊聊天, 裡面不乏有厲害的創業者, 或是從西雅圖到日本開發市場的 Google Developer Programs Engineer, Y! 的工程師, 甚至有穿著烏龜裝到處跟人聊天的 shiroyagi CEO 等等, 如果只有參加到最後的這個 Party 一切其實也都值得了!<br />
<br />
雖然我的程式功力沒有很厲害, 但是我會繼續對這個世界保持我的熱情。<br />
<br />
後註:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-vovOZWDkRZ0/VB7dHCY4rCI/AAAAAAAADuU/RJtW6cgeIgI/s1600/pyconjp2014_announcements.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="//2.bp.blogspot.com/-vovOZWDkRZ0/VB7dHCY4rCI/AAAAAAAADuU/RJtW6cgeIgI/s1600/pyconjp2014_announcements.png" height="192" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">據官方最後統計, 這屆參加者不含志工是 PyCon JP 最多人的一次</td></tr>
</tbody></table>
</div>
</div>
</div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-49854269748262840362014-08-23T12:43:00.000+08:002017-05-31T11:55:14.627+08:00談談 robots.txt 的 Disallow 和 Allow 順序昨天晚上在臉書上看到一篇熱門轉貼:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-ItAnkkpHOm4/U_gWa5awT9I/AAAAAAAADqw/ayQpRMH3LNc/s1600/blog_robots_txt.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="//3.bp.blogspot.com/-ItAnkkpHOm4/U_gWa5awT9I/AAAAAAAADqw/ayQpRMH3LNc/s1600/blog_robots_txt.png" height="640" width="562" /></a></div>
<br />
儘管原文有附一篇文章來佐證自己的看法, 但是基於自己對 robots.txt 的好奇及工程師喜歡驗證事情的吃飽太閒心態, 我做了個短短幾分鐘的驗證, 並記錄相關查詢資料如下。<br />
<br />
首先我必須揭露的是我對此次台北市市長候選人連勝文完全沒好感, 這篇文章單純只是探究 robots.txt 被誤導的特性。<br />
<a name='more'></a><br />
根據 Google 自己對<a href="https://support.google.com/webmasters/answer/6062596?hl=zh-Hant&ref_topic=6061961" target="_blank"> robots.txt 中可使用的關鍵字語法定義</a>是:<br />
<blockquote class="tr_bq">
User-agent: [the name of the robot the following rule applies to]<br />
Disallow: [the URL path you want to block]<br />
Allow: [the URL path in of a subdirectory, within a blocked parent directory, that you want to unblock]</blockquote>
經不負責翻譯轉換就是:
<br />
<blockquote class="tr_bq">
User-agent: [遵從下列規則的網路爬蟲(搜尋引擎漫遊器)名稱]<br />
Disallow: [你想要禁止網路爬蟲爬進去的網址]<br />
Allow: [位於子資料夾的網址, 在被禁止的父資料夾, 你想允許被爬蟲爬到的地方]</blockquote>
因此看起來 Disallow 跟 Allow 的擺放順序並不是如那篇熱門轉貼中所說的, 造成連勝文官網在 Google 上排行後面的主要原因。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-V9erSg4zySI/U_gXofIU3lI/AAAAAAAADq4/yOLnl2VoA20/s1600/blog_robots_txt_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="//2.bp.blogspot.com/-V9erSg4zySI/U_gXofIU3lI/AAAAAAAADq4/yOLnl2VoA20/s1600/blog_robots_txt_2.png" height="640" width="584" /></a></div>
<br />
避免因為是我將官方的英文解讀錯, 最後提供 <a href="https://www.google.com/robots.txt" target="_blank">Google 自己寫的 robots.txt</a> 來供大家驗證:<br />
<blockquote class="tr_bq">
User-agent: *<br />
Disallow: /search<br />
Disallow: /sdch<br />
Disallow: /groups<br />
Disallow: /images<br />
Disallow: /catalogs<br />
Allow: /catalogs/about<br />
Allow: /catalogs/p?<br />
Disallow: /catalogues<br />
Disallow: /news<br />
Allow: /news/directory<br />
...<br />
...</blockquote>
所以看起來並不是像那篇熱門轉貼上所說的, Disallow: / 擺在最前面導致其他文章沒被搜尋到, 更嚴格地說起來, 依照 Google 自己寫的定義跟 robots.txt 來看, "Disallow: 父資料夾"擺在 "Allow: 子資料夾"前面才是比較正確的做法。<br />
<br />
雖然那間外包公司出過了一次將 <a href="https://www.facebook.com/andretw/posts/10202678623786993" target="_blank">Debug Mode 打開讓大家看一些資訊</a>的包, 但是人家沒錯的部分應該還是要平衡報導一下。(看起來以後接專案也要測風向了, 不然會被一堆人打趴......)<br />
<br />
但是 Google 有提到, robots.txt 並不是強制的行為, 每家爬蟲的實作不一樣, 說不定有些順序有關也說不定, 不過至少看起來 Google 目前是沒這樣做就是了。Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-80389389957368916692014-06-05T23:50:00.004+08:002017-05-31T11:41:44.200+08:002014 外語導遊/領隊 (英語) 筆試口試考試心得<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-iszbQF5LRk0/U5AHm70U5AI/AAAAAAAADgo/AkArpUW0exQ/s1600/10259068_10202195795676592_427096819638017446_o.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="//3.bp.blogspot.com/-iszbQF5LRk0/U5AHm70U5AI/AAAAAAAADgo/AkArpUW0exQ/s1600/10259068_10202195795676592_427096819638017446_o.jpg" height="400" width="300" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">專業科目分數很不漂亮的成績單</td></tr>
</tbody></table>
去年 (2013) 看到新聞說導遊/領隊要考試了, 當時沒多想什麼就報名下去, 單純<strike>蠢</strike>只是想順便驗證自己對於所生活的台灣了解多少, 想說導遊/領隊的考試的及格標準是平均 60 分, 雖然很久沒考試, 或許可以靠不是很好的英文加一點分矇看看吧。先說結論, 最後我順利拿到外語導遊, 至於外語領隊則是平均差了 0.8 及格, 以一個筆試完全沒準備的人來說, 我覺得我算是蠻幸運的。(雖然我還是很懊惱為什麼在寫領隊的考卷時太悠哉而沒寫完十幾題, 只要多對個兩三題選擇題就可以兩張都到手了啊)<br />
<br />
相較於筆試的完全沒準備, 外語導遊的口試我倒是利用假日扎扎實實的準備了兩三天(剛好靠這個口試免了教召, 多吸了五天的自由空氣), 有時候在騎車、搭捷運時就會自言自語的開始小聲練習起來, 考試前幾天又因為發生了不幸的江子翠捷運事件, 在搭乘捷運的練習途中我常常很怕我被當成怪人給抓了起來......<br />
<br />
(註:筆試心得網路上很多, 因為我也沒啥心得, 我的心得只有原來國家考試會有一些莫名其妙的考題出現, 所以這篇文章主要在記錄口試的部分, 不過考完後我知道筆試前要多看觀光局網站, 聽說很多東西是從裡面考的, 法規也要讀, 不能像我一樣考出來就是送給他們或玩猜猜樂, 不過我本來原意就是要來測自己實力的, 看了感覺又好像作弊......)<br />
<br />
<a name='more'></a>再來說說考試當天的情況好了, 當天我是下午(第三)梯次的第一個, 緊張的我早上九點就到了國家考場。我在考場附近找了個可以練習口說的地方, 在考試之前不停地練習唯一自己能夠掌握的自我介紹, 因為考試的時間約 10 分鐘, 除了自我介紹外, 另外兩題題目是抽選而無法掌握的。於是我決定盡力讓自己的自我介紹維持在 4 到 5 分鐘左右, 加上強記一些英文的地名及熱門小吃的做法當作加分題, 就這樣, 我就臨陣磨槍上戰場了。<br />
<br />
雖然根據外語導遊口試的評分標準:<br />
<blockquote class="tr_bq">
一、外語表達能力,六十分。<br />
二、語音與語調,二十分。<br />
三、才識見解氣度,二十分。</blockquote>
裡頭完全沒有提到服裝儀容, 但是有一篇文章我覺得說的蠻有道理的, 穿得正式一點也不會被扣分, 所以我的標準寫 code 裝 (短褲加拖鞋) 很快就被排除了, 但是我又不太想要過於做作的感覺, 最後我穿了件我平常工作時會穿的襯衫和牛仔褲就應試去了。(我有看到有人穿全副自行車裝含安全帽進去口試, 蠻屌的。)<br />
<br />
意外的是, 我那梯次的缺考人數很多, 所以當我還在報到地點外面詢問一些雜事時, 就被監試人員趕著去報到和考試了(當天遇到的監試人員都不錯, 讓緊張的心情有稍微舒緩了些), 整整提早了近 20 分鐘, 雖然有點被驚嚇到, 但是經過不少小風小浪的我還是趕緊收拾好心情準備面臨考驗。<br />
<br />
先說整個口試流程大概是:<br />
<blockquote class="tr_bq">
到報到區報到(電子用品關機) ➞ 監試人員帶往考場 ➞ 抽題目 ➞ 計時 5 分鐘準備 ➞ 進入考場 ➞ 報中文姓名、准考證號碼及抽到的試題編號 ➞ 自我介紹 ➞ 兩題抽到的題目 ➞ 響鈴提醒 ➞ 結束</blockquote>
首先要注意的是, 到了報到地點進行報到後, 電子產品就不能再使用了, 像我這種把所有筆記都記在手機裡的考生只能哭哭了, 這時候可以看參考書和筆記, 卻不能用電子產品, 這規定實在讓我想不透啊。另外, 進入考場時只能帶著准考證, 那是要對著攝影機念出准考證號碼用的, 上面不能做任何筆記, 所以不管是你的自我介紹也好, 或是其他提醒自己的東西, 都只能記在腦袋裡。<br />
<br />
報到後會在一間教室裡等待著監試人員領你到考場外, 在考場外監試人員會先請你抽試題的題目編號, 我抽到的是 4 號, 緊接著把試題給你的同時, 會用碼表開始計時 5 分鐘, 5 分鐘後就會請你進去考場內應試。<br />
<blockquote class="tr_bq">
外語導遊(英語) <a href="http://www.ptt.cc/bbs/Tour-Manager/M.1401203555.A.E49.html" target="_blank">感謝批踢踢熱心版友 caca 提供</a><br />
01:自我介紹 介紹台灣的旅外棒球選手 台南安平<br />
02:自我介紹 介紹台北市垃圾不落地政策 花東地區<br />
03:自我介紹 介紹日月潭自行車道 說明北天燈南蜂炮<br />
04:自我介紹 介紹檳榔西施 台中市<br />
05:自我介紹 介紹台灣知名國際品牌 北海岸野柳公園<br />
06:自我介紹 介紹台灣氣候概況 宜蘭童玩節<br />
07:自我介紹 介紹台灣職棒 墾丁<br />
08:自我介紹 介紹台北捷運發展概況 澎湖<br />
09:自我介紹 介紹台灣夜市文化 馬祖<br />
10:自我介紹 介紹觀光工廠 綠島</blockquote>
根據上表所述, 我抽到的是介紹檳榔西施和台中市, 我只記得我寫了幾個大綱提醒自己:<br />
<ul>
<li>文化多元</li>
<li>違法性交易 (剛好前一天的新聞有報導)</li>
<li>人都喜歡欣賞美的事物</li>
<li>逢甲夜市</li>
<li>大甲鎮瀾宮</li>
<li>氣候怡人</li>
</ul>
<div>
然後 5 分鐘一下子就過了, 監試人員引導我進去後把自己的包包放好, 坐在兩位主考官的面前準備口試, 在對著攝影機說了我的中文姓名、准考證號碼及試題編號後, 主考官請我自我介紹, 我現在回想起來, 我那時候真的很緊張的, 老實說沒聽清楚他問什麼我就開始了我的自我介紹背誦行程。儘管演練過好幾次, 我的背誦還是很差, 好多個地方都是臨時新掰的, 儘管有些時候有稍微停頓一下, 但是往往幸運地在忘詞的瞬間有些不錯的脫稿演出。</div>
<div>
<br /></div>
<div>
我記得我一些拖稿演出的片段, 像是我有提到我是軟體工程師, 所以如果未來有機會當外語導遊時, 我希望能夠結合我目前的一些技能, 例如架設網站, 讓旅客可以自由選擇一些客製化的行程, 或是可以在網路上行銷台灣的美與好之類的。</div>
<div>
<br /></div>
<div>
接著就被問到對於檳榔西施的看法了。</div>
<div>
<br /></div>
<div>
我很誠實的說, 「As a man, no, I mean, as a human being, we all love the beauties, the beautiful things.」 (身為一個(男)人, 我的意思是, 身為一個人類, 我們都愛美(女), 美麗的事物) 嗯, 短短的一句話裡面有兩個雙關語, 我真不知道我那時候怎麼會說出這樣的話......</div>
<div>
<br /></div>
<div>
我另外提到雖然有些人會做一些非法的性交易, 導致檳榔西施對外的形象變差, 但是我認為台灣是個具有包容性且文化多元的社會, 這是台灣的特色, 也是我們熱愛她的理由。主考官怕我回答的時間不夠多, 還有接著詢問我覺得檳榔西施是好還是不好, 我只依稀記得我回答說: 「我覺得檳榔西施就是一份工作, 如果她沒有做違法的事情, 我覺得就是好的」儘管我認為性工作權也不該被限制、不該被當成違法的工作, 不過我那時候覺得這種在社會上還有些爭議的看法,不該在考試的時候說, 就選擇沒說了。</div>
<div>
<br /></div>
<div>
最後則是請我介紹台中市, 我必須承認, 我對台中市最想說的其實是「金錢豹」, 雖然我沒去過, 但是我還是很孬種的先提到了逢甲夜市, 我說那邊有很多美食, 也是很多著名小吃的發源地, 還有每年熱鬧的大甲鎮瀾宮媽祖繞境, 因為我實在不知道講什麼, 主考官還另外問了我覺得台中跟台北最大不同的地方在哪? 我用「Transportation」來回答。當然不是只有短短一個字, 我掰了很多很多的句子, 像是在台北, 我們可以很輕易地搭乘捷運跟公車去我們想去的地方, 但是在台中, 雖然有些捷運設施預計動工, 但是大部分的人現在還是都得仰賴計程車、自用小客車及機車來代步。 當然, 如果你知道盆地(basin)跟平原(plain)的英文怎麼說的話, 也是可以說......<br />
<br />
沒想到話匣子打開後, 時間一下就過去了, 提醒鈴聲響起後, <strike>依依不捨地</strike>趕快做個結尾謝謝主考官, 最後, 幸運地得到了 81.50 的口試分數, 真是老天保佑。<br />
<br />
後來考完下樓發生個小插曲, 離開前有遇到別的考生問我抽到什麼考題, 或許她是怕別人會藏私隱瞞, 所以她跟我說她是明年要考, 所以想知道一下今年的考題, 但是想也知道明年要考的人, 怎麼可能會在今年考試還沒結束, 就特地跑到國家考場樓下詢問考題呢? 不過因為我在趕公車, 匆匆忙忙地把檳榔西施跟台中市跟她說了之後就離開了。<br />
<br />
我覺得我蠻喜歡考這種自己及格就通過、沒有名額競爭的考試。這種只跟自己競爭的考試對我來說挺有學習的樂趣, 人生苦短, 每天都有學到一點新知識不就很開心了嗎?</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-68262065268108375862014-05-17T23:30:00.000+08:002017-06-04T20:30:07.833+08:00PyCon APAC 2014 Day 1 in Taipei<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-kAORBv_ICg8/U3ebzdD-7YI/AAAAAAAADfM/xIinn4-xKZ0/s1600/PyCon_APAC_2014_Taipei_Andre_Lee_with_Stephen_McDonald.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="//2.bp.blogspot.com/-kAORBv_ICg8/U3ebzdD-7YI/AAAAAAAADfM/xIinn4-xKZ0/s1600/PyCon_APAC_2014_Taipei_Andre_Lee_with_Stephen_McDonald.jpg" width="300" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">當個小粉絲跟 <a href="http://www.andretw.com/2014/04/customize-your-mezzanine-content-management-platform.html" target="_blank">Mezzanine</a> 的作者 <a href="https://github.com/stephenmcd" target="_blank">Stephen McDonald</a> 合照, 先跟他小小抱怨了沒有 i18n 的痛苦, 他說那是現在排名第一名的 Missing Feature, 他回去就會把 pull requests 好好的 merge 回去了</td></tr>
</tbody></table>
五月似乎是所有的事情都擠在一起發生, 由於去年 PyCon 舉辦的時間剛好跑去澎湖花火節而錯過了, 所以儘管被一堆事卡著, 還是決定參加湊熱鬧。<br />
<br />
今天(5/17)有些蠻有趣的心得, 希望對資訊或數學有興趣的人可以花點時間看一下, 沒有太高深的東西(太高深的我也不會), 僅僅是點到為止的介紹。<br />
<br />
<h4>
Keynote</h4>
<br />
首先從今天的 Keynote 開始, 主講者是來自 DataPad 的 <a href="http://blog.wesmckinney.com/" target="_blank">Wes McKinney</a>, 他同時是 <a href="http://pandas.pydata.org/" target="_blank">Pandas</a> 和 <a href="http://shop.oreilly.com/product/0636920023784.do" target="_blank">Python for Data Analysis</a> 的作者。他的講題主要的方向可能是從他自身經驗(BI, 商業邏輯) 來導出 Python 在資料科學的趨勢、重要性及實用性。<br />
<br />
接著提到在資料科學中的 ETL (Extract, Transform, Load) 不是件容易的事, 很多人認為, 在資料科學中往往最困難的不是在資料分析, 而是在資料的導入與取得上面。對此, 他也引用了 Big Data Borat 在 Twitter 上說的話來提供這觀點的共鳴(註:真的!):<br />
<a name='more'></a><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-jiNQFOyLx2c/U3bH5MPpmkI/AAAAAAAADew/5RWKuLOMUrA/s1600/PyCon_APAC_2014_Taipei_keynote_Big_Data_Borat_png.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="In Data Science, 80% of time spent prepare data, 20% of time spent complain about need for prepare data. " border="0" src="//1.bp.blogspot.com/-jiNQFOyLx2c/U3bH5MPpmkI/AAAAAAAADew/5RWKuLOMUrA/s1600/PyCon_APAC_2014_Taipei_keynote_Big_Data_Borat_png.png" title="" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="https://twitter.com/BigDataBorat/status/306596352991830016" target="_blank">在資料科學中, 大概花百分之八十的時間在準備資料, 另外百分之二十在抱怨準備那些必要的資料<br />-- Big Data Borat</a></td></tr>
</tbody></table>
<br />
最後他則提出一句他自己也不知道是誰說的話來作結尾:<br />
<blockquote class="tr_bq">
Python is the second best language for Data Science</blockquote>
這句話在 PyCon 講可能會引起公憤, 不過講者立刻解釋說因為很多人都會擁護自己愛戴的語言, 像是有些人會覺得 Scala 比較好, 有些人則是認為 Java 比較好之類的, 但是這種情況底下, 通常大家都會願意折衷取一個效率雖然不是最好, 但卻大家都能夠接受的 Python 來實作, 對 Python 實際上是個幽默的讚美。<br />
<br />
<h4>
PySpark: next generation cluster computing engine</h4>
<br />
第二個聽的是來自 Yahoo! 奇摩 Wisely Chen 給的 talk, PySpark 其實在我去年寫這篇參加 <a href="http://www.andretw.com/2013/09/apache-spark-shark-are-faster-than-hadoop-yahoo-tech-conference.html" target="_blank">Yahoo! 技術分享活動的文章</a>中多少可以得到這個 talk 的重點, 由於上次 Spark 的作者講的蠻仔細的, 這次有多的部分可能就是在展示利用 PySpark + scikit-learn 簡單實作<a href="https://www.google.com.tw/search?newwindow=1&es_sm=119&q=%E6%8E%A8%E8%96%A6%E7%B3%BB%E7%B5%B1+Machine+Learning&oq=%E6%8E%A8%E8%96%A6%E7%B3%BB%E7%B5%B1+Machine+Learning&gs_l=serp.3...7993.19710.0.19929.14.14.0.0.0.1.182.1189.9j5.14.0....0...1c.1.43.serp..11.3.220.Ly2bqjwfuJs" target="_blank">推薦系統</a>的部分。從這個講題我們可以確認, 在經過了快一年後, Spark / Shark 真的是現在想要研究 Big Data 的朋友需要了解的趨勢之一, 想走 Big Data 路線的朋友, 千萬千萬不要遺漏了。<br />
<br />
<h4>
Time for Education: Data Mining in High School</h4>
<br />
接下來我去聽的是一位來自新加坡的高中生, Yuli Zhan, 分享他做的一些關於中學教育的專題, 新加坡的英文真的好, 教育感覺也很活, 從國高中就有 study group, 真是讓人羨慕啊。講者提到一些資料科學在教育上可能的應用, 像是如果一個學生在學習過程中分別陸續得到 EEEAA 或 AAEEE 這兩種分數的排列, 在這種情況底下, 最後學期末可能都是得到 C 左右的平均分數, 但是如果善用資料分析, 可以看出學生是在成長還是退步, 進而事先預防找出盲點與困境, 這樣的觀點在申請國外的學校也可以發現異曲同工之妙, 國外的學校會在乎你成績是否是逐漸上昇的(好證明你是有潛力及企圖心的), 所以有些會看最後幾學期的分數, 而不是單單僅是看最後的平均, 不過名校可能就是大家都 GPA 4.0 滿分, 不過我自始至終沒申請過, 單純打打嘴炮一下。<br />
<br />
<h4>
Graph-Tool: The Efficient Network Analyzing Tool for Python</h4>
<br />
上午的最後一場是 <a href="http://www.pinkoi.com/" target="_blank">Pinkoi</a> 的 <a href="http://mosky.tw/" target="_blank">Mosky Liu</a> 講的主題, 主題臨時改成 Graph-Tool in Practice, 是一場蠻實用的 talk。其中提到在開始前需要進行一些步驟, 像是,
<br />
<ol>
<li>定義問題</li>
<li>轉換成圖</li>
<li>處理原始資料</li>
</ol>
第一點中她所舉的例子是她們想要提高顧客的停留時間, 以及知道顧客偏好的瀏覽流程之類的, 在確認了問題之後, 接著需要的是進行第二點的步驟, 將問題轉換成圖, <a href="https://speakerdeck.com/mosky/graph-tool-in-practice" target="_blank">簡報</a>的第 11 頁有提到, 將圖論中的點和邊, 根據權重或自定義的條件畫出圖來, 從圖中或許可以很容易找出 closeness 的點, 在資料分析中, 圖可以讓我們更清楚知道彼此的關係, 這也是為什麼資料視覺化也越來越重要的緣故。第三點關於處理原始資料的部分, 她則提到一些像是 regular expression 撰寫可以事先濾掉 (filtering) 不需要的資料, 以及可以考慮先對資料進行排序來增加效率。還有提到 <a href="https://docs.python.org/2/library/pickle.html" target="_blank">Pickle</a> 這個可以將 object 進行 serializing 和 de-serializing 的 package, 她有提到要對它進行一些設定, 這部分就請自己參照自己的需求設定,<br />
<ul>
<li>設定 HIGHEST_PROTOCOL</li>
<li>採用 tuple 以節省空間與時間</li>
<li>將檔案序列化存檔</li>
</ul>
或許如果可以多利用這些在現實生活中的例子, 可以讓喜歡資訊的人, 在學組合(離散)的時候, 感到更有興趣和親切(雖然我本來就蠻喜歡組合的)。<br />
<br />
<h4>
IPython in PNaCl</h4>
<br />
下午第一場由 UC Berkeley, 同時也是 IPython 作者 <a href="https://github.com/fperez" target="_blank">Fernando Perez</a> 所演講, 雖然剛吃飽飯想睡覺, 我還是很認真的把英聽給上完了。:D<br />
<br />
這個 talk 提到了 Python 和 Science 的關係, 也提到了資料科學的重要性, 對我來說最有趣的是 IPython。我一開始在想 IPython 不就只是個 interactive (互動式) 的 Python shell 嗎? 這樣原生 Python 不是也有提供嗎?<br />
<br />
但是如果加上 Google Drive 之後呢?<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/mbMpDo9t1UQ#t=188" width="420"></iframe>
<br />
<br />
竟然變成了協作的 IPython... 真的還蠻有趣的就是了, 但是目前我似乎沒有這樣需求的情境可以套用, 可能還需要再想一下, 先放進腦袋裡備用。<br />
<br />
<h4>
graph database for python</h4>
<br />
由 tagtoo 李宗哲所提供的 talk, 好像是提到 neo4j, 因為之前已經聽過比較深的講題, 我就不自覺的晃神了......<br />
<br />
<h4>
Yielding a Tulip</h4>
<br />
Yielding a Tulip 這個由 Tzu-ping Chung 所分享的主題其實很有趣, 因為 Tornado 就是用類似概念這樣搞的(誰致敬誰的我還沒查), 不過這個原理在去年, 有一個我超閒(<a href="http://achichen-blog.logdown.com/posts/143510-sanshing-town-area-with-the-yuanshanxiang-who" target="_blank">三星鄉與員山鄉誰的面積大?</a>)又亦師亦友的強者喇賽夥伴 <a href="http://www.linkedin.com/pub/achi-chen/38/849/430" target="_blank">Achi Chen</a>, 曾經用 PyDev 去 trace Tornado 的 event loop 然後分享給我知道, 如果真的有人想知道, 我會請他出山來寫一篇文章滿足大家的求知慾。<br />
<br />
<h4>
Data Analysis in Python</h4>
<br />
這個由 Wei-Ting Kuo 所分享的主題偏向資料分析所需要使用到的 Python 基礎, 我沒有聽完全程跑去聽上面的那場 talk 了, 歡迎有聽完的朋友可以分享一下。<br />
<br />
<h4>
Lightening talk</h4>
<div>
<br />
Lightening talk 真的是現在這些研討會後我最喜歡的一個部分, 參加的人都很有創意, 有些無俚頭搞笑的、有些認真做小玩具的、有些假心得抱怨文的, 總之, Lightening talk 真的不能錯過。(僅先用我筆記的重點先擺著, 晚點補回細節)</div>
<ul>
<li>mooc.org, edX.org</li>
<li>PyClab</li>
<li>show code </li>
<li><strike>TDD</strike> BoF is dead</li>
<li><span style="color: red;">programming and music</span></li>
<li>窮人的 BigQuery, QSearch -> google analytics</li>
<li>Taiwan R user group</li>
<li>ZipCodeTW</li>
<li>pelican</li>
<li>one line code, checkio</li>
<li>NetworkX, closeness, centrality</li>
<li>ciphers using python</li>
<li>Hue</li>
<li>Capy, 日籍 CTO 上台介紹 Capy </li>
</ul>
<div>
中間我最喜歡的是由同時也從趨勢出來的 <a href="https://github.com/yychen" target="_blank">Tom Chen</a> 所展示, 有關程式與音樂結合的小專案, 利用簡單音源辨識, 流暢的簡報過程, 是一個非常不錯的短講。至於其他的 talk, 蠻多東西之前或多或少有摸過, 不過應該會將窮人版的 BigQuery、Cloudera 的 <a href="https://github.com/cloudera/hue" target="_blank">Hue</a> 、NetworkX 列為有空可以摸摸看的小東西, 似乎蠻值得玩一下的。不過, 前提還是要有空看啊, 雖然乳溝變大了, 但是還是挺難擠的......<br />
<br />
<h4>
BoF, Birds of a Feather</h4>
<br />
在 BoF 時間, 我把披薩盒給撕開, 幫忙寫了個海報進行招募, 效果感覺還不錯, 蠻多人來詢問的。<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-RcNBq5R6dOs/U3gThZ5XFPI/AAAAAAAADfk/ebDHRXTYWKs/s1600/PyCon_APAC_2014_Taipei_BoF_promote_Capy.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="//2.bp.blogspot.com/-RcNBq5R6dOs/U3gThZ5XFPI/AAAAAAAADfk/ebDHRXTYWKs/s1600/PyCon_APAC_2014_Taipei_BoF_promote_Capy.jpg" width="300" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">sushi 就是模特兒身材啊</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-mJxLF76wS0Y/U3gTruFZKXI/AAAAAAAADfs/MMM_DGAykBc/s1600/PyCon_APAC_2014_Taipei_BoF_promote_Capy_after.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="300" src="//1.bp.blogspot.com/-mJxLF76wS0Y/U3gTruFZKXI/AAAAAAAADfs/MMM_DGAykBc/s1600/PyCon_APAC_2014_Taipei_BoF_promote_Capy_after.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">有了海報立馬很多人來詢問, 看來日本的吸引力很大啊 XD</td></tr>
</tbody></table>
後註:Capy 是一間跟我們之前在<a href="http://www.andretw.com/2011/12/what-have-I-learned-from-1th-startup-weekend-Hsinchu-with-HitCAPTCHA.html" target="_blank"> Startup Weekend 得獎作品</a>類似的新創公司(已經獲得日本知名創投融資), 我們當初成員之一目前在裡面奮戰中, 對 Python、Django 有興趣, 也想前往日本工作的朋友, 歡迎談談。<br />
<br />
後後註:其實從11點寫到了星期天的凌晨1:40, 但是因為懶得改上面原本使用今天的詞, 決定偷改文章日期時間......</div>
<div>
<br />
後後後註:免責聲明, 因為本人可能在做筆記的時候遭遇晃神、聊天等不可抗拒之外力影響, 筆記內容難免有落差, 如有正確資訊, 煩請指正。</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-19965779790784092262014-04-25T00:28:00.000+08:002014-04-27T18:41:17.501+08:00[Mezzanine] 利用 Django 的 Middleware 機制進行多國語系 (I18N) 處理 (使用 JavaScript 的解決方案)<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-jeuYTsk7_Mg/U1zF9Ra-AyI/AAAAAAAADc8/vKz8pCvzo1g/s1600/mezzanine_i18n_best_practice.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://2.bp.blogspot.com/-jeuYTsk7_Mg/U1zF9Ra-AyI/AAAAAAAADc8/vKz8pCvzo1g/s1600/mezzanine_i18n_best_practice.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Mezzanine i18n Best Practice (對我們而言最佳的解決方案)</td></tr>
</tbody></table>
由於 Mezzanine 對多國語系的處理感覺還在起步階段, 而原作者 <a href="https://github.com/stephenmcd">Stephen McDonald</a> 在一則類似問題中所提出的<a href="http://grokbase.com/t/gg/mezzanine-users/13aq38jxrf/i18n-custom-page-responding-to-current-locale" target="_blank">替代方案</a> (approch) 為在後台新增多個站台, 並將各國語言分別指向各個站台, 這樣的意思是說, 倘若今天一篇文章需要 16 種的語言翻譯, 就必須要分別上稿至 16 個網站, 按照管理系統的設計, 就是要切換 16 次到不同網站, 然後再分別新增文章......我想如果我們這樣搞的話, 這樣的解決方案可能會被罵死, 因此, 我們決定對這個部分進行一些客製化。<br />
<br />
<b>目標:</b><br />
<blockquote class="tr_bq">
使用者進入網站時, 判斷最合適語言, 利用 JavaScript (AngularJS) 函數將所需要翻譯的文字進行替換</blockquote>
<br />
<a name='more'></a>首先先在 settings.py 裡面新增一個 Middleware:<br />
<br />
<script src="https://gist.github.com/andretw/11340242.js?file=add_middleware_in_settings.py"></script>
接著強迫每一個頁面都必須要有 lang 這個 query parameter (除了 static files 和 admin 等):
<br />
<br />
<script src="https://gist.github.com/andretw/11340242.js?file=selectlang.py"></script>
新增一個 JavaScript 函數 _(key) 讓需要翻譯的文字透過這個函數進行轉換:
<br />
<br />
<script src="https://gist.github.com/andretw/11340242.js?file=selectlang.coffee"></script>
最後再加上翻譯檔與 template 的檔案, i18n 的機制的完工了 (備註):<br />
<br />
<script src="https://gist.github.com/andretw/11340242.js?file=zh_TW.js"></script>
<script src="https://gist.github.com/andretw/11340242.js?file=base.html"></script>
不過這當中我們還有利用一些技巧及為了內部翻譯流程順暢而蓋的輪子(可能算是大車子了...)沒有寫出來, 如果有人有興趣, 說不定可以有機會請搭建車子的強者我同事出來現身說法一下。<br />
<br />
<a name="interpolate"></a>備註:由於 Python 蠻多 template engine (樣板引擎) 所預設用的渲染 (render 或叫插入 interpolate) 符號跟 AngularJS 一樣, 所以必須要修改 AngularJS 或是 Python 兩者其一的預設渲染符號。網誌中的範例是如下在 AngularJS 的 config 階段修改 AngularJS 的渲染(插入)符號。<br />
<br />
<script src="https://gist.github.com/andretw/11340242.js?file=interpolate.coffee"></script>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-35920062672035983102014-04-24T23:46:00.003+08:002014-04-27T18:39:49.290+08:00客製化 Mezzanine - A Content Management Platform (or CMS) Built Using the Django Framework<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-HZMiuVTLldc/U0aHb9zrLwI/AAAAAAAADcA/YrcaSu5zf3I/s1600/Customize_your_mezzanine_title.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://4.bp.blogspot.com/-HZMiuVTLldc/U0aHb9zrLwI/AAAAAAAADcA/YrcaSu5zf3I/s1600/Customize_your_mezzanine_title.png" height="156" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Mezzanine, an open source content management platform</td></tr>
</tbody></table>
<a href="http://mezzanine.jupo.org/" target="_blank">Mezzanine</a> 是一套建構在 <a href="https://www.djangoproject.com/" target="_blank">Django</a> 上的 <a href="http://cms/" target="_blank">CMS</a>。安裝系統的過程很簡單, 輕鬆地輸入幾個指令, 就可以快速擁有一個美觀界面可以使用的內容管理系統了。不過呢, 如果想要更進一步地客制化它, 從了解設計哲學到完成一些小目標, 也算是一個可以學到很多東西的主題。<br />
<br />
兩個禮拜說長不長, 說短不短, 在這段時間中不停地在<a href="https://github.com/stephenmcd/mezzanine" target="_blank">原始碼</a>、文件、Stackoverflow、及<a href="https://groups.google.com/forum/#!forum/mezzanine-users" target="_blank">討論區</a>中來回查找、驗證, 在茫茫的資訊海中要找到本來資料就不多 Mezzanine, 學習門檻不可謂不高, 因此在對它有一些的了解後(Django藏了太多東西, 要全部了解還是要繼續摸), 儘管深怕班門弄斧會誤導觀眾, 但是避免這些對我來說很寶貴的經驗被太快遺忘掉, 希望透過這篇網誌來整理一下先前的思緒與成果, 倘若還可以意外地釣到一些野生的前輩或先進分享經驗指教, 那可更是感動萬分啊。<br />
<br />
先大概介紹一下這次 (已經完成的) 客製化目標或遇到的問題:<br />
<ol>
<li>讓一個 Mezzanine 有兩(多)個 Blog 系統</li>
<li><a href="http://www.andretw.com/2014/04/customize-your-mezzanine-with-Django-middleware-and-JavaScript-AngularJS-for-i18n-multilingual.html">利用 Django 的 Middleware 機制進行多國語系 (I18N) 處理 (使用 JavaScript 的解決方案)</a></li>
<li>對 RichText Page 新增客製化欄位</li>
<li>Django/Mezzanine 處理靜態檔案 (STATIC_URL, STATIC_ROOT, MEDIA_URL, MEDIA_ROOT)</li>
<li>利用 context_processor 新增 template 裡面所需使用的變數</li>
<li>使用 Gunicorn 透過 WSGI 使用 Unix Socket 與 Nginx 溝通</li>
<li>啟用 SSL (HTTPS)</li>
<li>增加 Admin 管理界面開啓關閉選項</li>
<li>Logging, 最重要的程式日誌設定</li>
<li>CentOS 上利用 pip 安裝 Mezzanine 會發生的問題</li>
<li>客製化 TinyMCE (RichText Editor) 新增按鈕及功能</li>
<li><a href="http://www.andretw.com/2014/04/customize-your-mezzanine-with-Django-middleware-and-JavaScript-AngularJS-for-i18n-multilingual.html#interpolate">解決 AngularJS 與 template 使用相同 {{ }} 符號</a></li>
</ol>
<div>
問題與說明放在上述目標連結上, 如果還沒放連結, 表示還沒寫完。至於利用 Puppet、<a href="http://www.andretw.com/search/label/Supervisor">Supervisor</a> 及 fabric 進行部署與管理的系統層面則不在本次文章範圍內。</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4783512064634308801.post-44157566188526859122014-04-06T17:38:00.000+08:002014-04-07T10:35:24.538+08:00如何抵制造假的電視媒體?如台灣中X、TXBS之類的新聞頻道<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-TisQwHZqVl0/U0EdV4FtwoI/AAAAAAAADbI/NR81bkQ75bs/s1600/how-to-boycott-the-fake-news-making-media-like-cxv-txbs-1.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-TisQwHZqVl0/U0EdV4FtwoI/AAAAAAAADbI/NR81bkQ75bs/s1600/how-to-boycott-the-fake-news-making-media-like-cxv-txbs-1.jpg" height="424" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">踢倒垃圾桶在拍攝的媒體, 最後聲明是不小心踢倒的(<a href="http://www.worldjournal.com/view/full_van_14/24817728/article-SNG%E8%BB%8A%E6%B7%AA%E9%99%B7-TVBS-%E7%B5%95%E4%B8%8D%E9%80%A0%E5%81%87?instance=bcnews2" target="_blank">來源</a>)</td></tr>
</tbody></table>
新聞,是一種從我們小時候學作文開始, 就知道這種文章不該帶有個人思想與情感的文體, 記者的責任不但應該客觀中立的報導, 更必須進行初步、甚至進階地確認事件的真實性後才能出刊。然而, 現在有些記者揮舞著新聞自由的大旗, 將確認新聞真實性的責任, 轉嫁給閱聽者自行判斷, 這不僅嚴重喪失了記者該有的道德底線, 更背棄了社會對他們擔任第四權的期待。<br />
<br />
<a name='more'></a>更遑論如中X集團、TXBS之流, 不但報導未經查證的事實, 更尤甚者, 將新聞從業自我降格為新聞製造業, 對付如此沒有格調, 卻擁有龐大資源與發言權的媒體時, 平凡如你我的小老百姓該怎麼做?如果你看得到這篇文章, 甚至把它讀完並轉載, 恭喜你, 你應該不需要採取任何的行動來避免自己的看法被不入流的媒體誤導, 但是如果你身邊的朋友或親人仍舊瘋狂相信中X、TXBS之類的新聞是真實報導的話, 請你跟著下面的步驟這樣做。儘管可能會落得「意見單一化」的惡名, 但是兩害相權取其輕, 寧願意見單一化, 也不願看到意見造假化。<br />
<br />
那該怎麼做?其實很簡單, 只要<b>將你家的電視頻道設定忽略這幾台造假的頻道</b>, 讓他們看不到這幾台的新聞就好。由於會對中X、TXBS深信不疑的人通常是很少接觸到網路的族群, 所以常常無法接觸到真實的新聞或反方的意見, 就因為這樣, 電視與報紙常常是他們唯一接觸事情資訊的來源, 再加上惰於思考的緣故, 有些人會將那些媒介的評論當作自己的評論講出來(註一), 他們以為那些媒體有經過查證、查實, 卻從沒想過那些不入流的媒體竟然連這些基本的工作都沒做, 把一坨捏造的大便就這樣餵給支持它們的閱聽人。<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-xGq3Km7SRoY/U0EZ19_AhxI/AAAAAAAADa8/5aFRYOU659Y/s1600/how-to-boycott-the-fake-news-making-media-like-cxv-txbs.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://4.bp.blogspot.com/-xGq3Km7SRoY/U0EZ19_AhxI/AAAAAAAADa8/5aFRYOU659Y/s1600/how-to-boycott-the-fake-news-making-media-like-cxv-txbs.jpg" height="360" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">如何忽略掉惡質頻道, 以LG系統為例</td></tr>
</tbody></table>
所以, 為了拯救他們的你只需要如上圖所述這麼做(註三):<br />
<blockquote class="tr_bq">
以 LG 的電視系統為例(不好意思我現在只有LG的電視, 改天回家我會再補上其他牌子), 只要在遙控器上點選「設定」-> 「頻道」再到欲忽略的頻道上點選藍色按鈕即可完成。(註四)</blockquote>
對了, 如果你還狗屎運有機會上這種愛造假的霉體, 不要太過高興, 可能你會意外被他們高超的剪接技巧剪成明明你說「我愛台灣, 不支持黑箱」, 變成「我愛黑箱, 不支持台灣」都有可能。<br />
<br />
所以為了自保, 在霉體開始訪問前, 記得打開手機的碼表放在自己的脖子旁邊, 或是打開手機錄影模式, 將鏡頭指向自己, 他們的奧步就會一步一步被揭穿了。<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-0GSHC8hZt4o/U0FpPkSdBKI/AAAAAAAADbk/q_Kal_HhO3A/s1600/how-to-boycott-the-fake-news-making-media-like-cxv-txbs-mobile.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://2.bp.blogspot.com/-0GSHC8hZt4o/U0FpPkSdBKI/AAAAAAAADbk/q_Kal_HhO3A/s1600/how-to-boycott-the-fake-news-making-media-like-cxv-txbs-mobile.png" height="320" width="194" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">千萬別太開心導致忘記開碼表或是開錄影</td></tr>
</tbody></table>
<br />
註一:有關新聞造假事件如下:<br />
<ul>
<li><a href="http://www.ptt.cc/bbs/HatePolitics/M.1396510179.A.C90.html" target="_blank">[黑特] 中天:新聞自由不容干擾</a></li>
<li><a href="http://iservice.libertytimes.com.tw/liveNews/news.php?no=974939" target="_blank">遍地開花》電子媒體涉造假 便利貼嗆聲</a></li>
<li><a href="http://www.peopo.org/news/237685" target="_blank">中天物化學運女性犯眾怒 檢舉灌爆NCC</a></li>
<li><a href="http://www.ptt.cc/bbs/FuMouDiscuss/M.1396752279.A.EA7.html" target="_blank">[爆料] 在立院內的黃粱一夢</a></li>
<li>不勝枚舉...</li>
</ul>
註二:王炳忠將別人餵給他說協議只能包裹表決的看法轉述, 卻被國際法專家駁斥:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/y7kAf-sH7JQ?feature=player_embedded' frameborder='0'></iframe></div>
<br />
註三:如果他們可以破解這簡單的技巧, 那你也不用擔心他們會被誤導了, 因為他們知道如何去找尋答案。這個方法通常也只有按「上一台」、「下一台」的時候會被忽略, 如果已經深深牢記頻道號碼的人, 直接選擇頻道號碼仍然可以看到。<br />
<br />
註四:因為我自己住的地方已經將有線電視停掉, 看不到那些惡質頻道了, 但是惡質頻道的集團勢力實在太廣了, 幾乎無所不包, 連報紙都想要半買半相送的進入我們住家社區, 果然資本的力量很恐怖。Unknownnoreply@blogger.com0