<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Flashlight</title>
	<atom:link href="http://q.pnq.cc/feed" rel="self" type="application/rss+xml" />
	<link>http://q.pnq.cc</link>
	<description>Flash, Game, Web</description>
	<lastBuildDate>Thu, 16 Feb 2012 03:30:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>fdlint: 让前端code review更轻松</title>
		<link>http://q.pnq.cc/archives/603</link>
		<comments>http://q.pnq.cc/archives/603#comments</comments>
		<pubDate>Mon, 13 Feb 2012 12:04:46 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- Misc：其他 -]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=603</guid>
		<description><![CDATA[fdlint是bencode 和 我最近做的一个实用项目。她的参考是jslint——一个js代码扫描工具。和jslint不同的是，fdlint还可以扫描css和html代码。 为什么会做fdlint？ Code review是一项重要却比较花时间的工作，根据阿里巴巴中文站前端Code Review Check List，约有80项检查项目，要完整对照着检查是比较花时间的。太花时间导致的结果就是code review的频率不高。 因此，我们开发了fdlint，对HTML/CSS/JS代码进行分析，找出工具能判断的、不符合规范的代码。fdlint可以节约我们的时间，帮助 code review 更频繁、更深入。 特点： 能扫描出不符合规则的常见问题，共49项, 详见扫描规则 提供多种使用方式，适合不同的应用场景 （命令行、web、VIM插件、Notepad++插件、Eclipse插件） 规则定制方便，将用DSL编写的规则放入一个目录，立刻生效。 可以批量扫描多个文件，支持递归扫描目录 支持多种输出格式 截图 命令行运行 web版本 Eclipse插件 Notepad++插件 VIM插件]]></description>
			<content:encoded><![CDATA[<p><img src="http://img.china.alibaba.com/img/ibank/2012/462/137/490731264_678162280.jpg" alt="fdlint" style="border:none;" /></p>

<p><a href="https://github.com/qhwa/fdlint">fdlint</a>是<a href="http://bencode.org">bencode</a> 和 我最近做的一个实用项目。她的参考是<a href="http://jslint.com">jslint</a>——一个js代码扫描工具。和<a href="http://jslint.com">jslint</a>不同的是，<a href="https://github.com/qhwa/fdlint">fdlint</a>还可以扫描css和html代码。</p>

<h2>为什么会做<a href="https://github.com/qhwa/fdlint">fdlint</a>？</h2>

<p>Code review是一项重要却比较花时间的工作，根据阿里巴巴中文站前端Code Review Check List，约有80项检查项目，要完整对照着检查是比较花时间的。太花时间导致的结果就是code review的频率不高。</p>

<p>因此，我们开发了<a href="https://github.com/qhwa/fdlint">fdlint</a>，对HTML/CSS/JS代码进行分析，找出工具能判断的、不符合规范的代码。<a href="https://github.com/qhwa/fdlint">fdlint</a>可以节约我们的时间，帮助 code review 更频繁、更深入。</p>

<h2>特点：</h2>

<ol>
<li>能扫描出不符合规则的常见问题，共49项, 详见<a href="https://github.com/qhwa/fdlint/wiki/fdlint-%E6%89%AB%E6%8F%8F%E8%A7%84%E5%88%99">扫描规则</a></li>
<li>提供多种使用方式，适合不同的应用场景 （命令行、<a href="http://fdlint.herokuapp.com">web</a>、<a href="https://github.com/qhwa/fdlint-vim">VIM插件</a>、<a href="https://github.com/ThinkBest/fdlint-notepad-plusplus">Notepad++插件</a>、Eclipse插件）</li>
<li>规则定制方便，将用DSL编写的规则放入一个目录，立刻生效。</li>
<li>可以批量扫描多个文件，支持递归扫描目录</li>
<li>支持多种输出格式</li>
</ol>

<h2>截图</h2>

<ul>
<li><p>命令行运行</p>

<p><img src="http://q.pnq.cc/wp-content/uploads/2012/02/fdlint-cli-500x619.png" alt="" title="fdlint-cli" width="500" height="619" class="alignnone size-medium wp-image-607" /></p></li>
<li><p>web版本</p>

<p><img src="http://q.pnq.cc/wp-content/uploads/2012/02/fdlint-host-500x512.png" alt="" title="fdlint-host" width="500" height="512" class="alignnone size-medium wp-image-609" /></p></li>
<li><p>Eclipse插件</p>

<p><img src="http://q.pnq.cc/wp-content/uploads/2012/02/fdlint-eclipse-500x140.png" alt="" title="fdlint-eclipse" width="500" height="140" class="alignnone size-medium wp-image-608" /></p></li>
<li><p>Notepad++插件</p>

<p><img src="http://q.pnq.cc/wp-content/uploads/2012/02/fdlint-notepad-500x414.png" alt="" title="fdlint-notepad" width="500" height="414" class="alignnone size-medium wp-image-610" /></p></li>
<li><p>VIM插件</p>

<p><img src="http://q.pnq.cc/wp-content/uploads/2012/02/fdlint-vim-500x543.png" alt="" title="fdlint-vim" width="500" height="543" class="alignnone size-medium wp-image-611" /></p></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/603/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Say Hello To My New Mate</title>
		<link>http://q.pnq.cc/archives/597</link>
		<comments>http://q.pnq.cc/archives/597#comments</comments>
		<pubDate>Thu, 09 Feb 2012 12:53:51 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- Misc：其他 -]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=597</guid>
		<description><![CDATA[没错，这是我的新伙伴，今天正式开始我的骑行了，2012的一大目标就是锻炼身体！ 今天在网上看中的，下午联系，晚上就提车了，真是爽快！ 因为信任骑行的人，我对车主“死魂灵”是完完全全的信任，虽然我还是车盲一个，哈哈！ 提车的时候，死魂灵无微不至的交代，各种经验之谈浓缩在短短的十分钟之内，从车的调节，到刹车的时候，还有分别时候的关于安全的交代。。我囫囵吞枣般地都短暂记住了，那个场景让我想起了小说里的场面：一个武功高手在传内力给一个战斗力只有5的小朋友。。]]></description>
			<content:encoded><![CDATA[<p>没错，这是我的新伙伴，今天正式开始我的骑行了，2012的一大目标就是锻炼身体！</p>

<p><img src="http://q.pnq.cc/wp-content/uploads/2012/02/DSC_0824-500x752.jpg" alt="bike" />
<img src="http://q.pnq.cc/wp-content/uploads/2012/02/DSC_0823-500x332.jpg" alt="bike" /></p>

<p>今天在网上看中的，下午联系，晚上就提车了，真是爽快！
因为信任骑行的人，我对车主“死魂灵”是完完全全的信任，虽然我还是车盲一个，哈哈！
提车的时候，死魂灵无微不至的交代，各种经验之谈浓缩在短短的十分钟之内，从车的调节，到刹车的时候，还有分别时候的关于安全的交代。。我囫囵吞枣般地都短暂记住了，那个场景让我想起了小说里的场面：一个武功高手在传内力给一个战斗力只有5的小朋友。。</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/597/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Ubuntu下在命令行批量生成缩略图</title>
		<link>http://q.pnq.cc/archives/584</link>
		<comments>http://q.pnq.cc/archives/584#comments</comments>
		<pubDate>Tue, 29 Nov 2011 13:21:32 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- linux -]]></category>
		<category><![CDATA[batch]]></category>
		<category><![CDATA[generating]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[imagemagick]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[thumbnail]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=584</guid>
		<description><![CDATA[# 准备工作：安装 imagemagick sudo apt-get install imagemagick cd /path/to/big/images #大图所在的目录 #创建小图对应的目录结构 find . -type d -print -exec mkdir '../small/{}' -p \; #批量转换! 等比例缩小到320x320之内 find . -type f -name '*.jpg' -print -exec \ convert '{}' -resize 320x320 '../small/{}' \; 这样小图都会按原先的目录结构，在上级目录的small目录出现了 其实imagemagick是一个超级神器，上面只是它很简单的一个应用&#8230;]]></description>
			<content:encoded><![CDATA[<pre class="lang-bash"><code><span class="co0"># 准备工作：安装 imagemagick</span><br />
<span class="kw2">sudo</span> <span class="kw2">apt-get</span> <span class="kw2">install</span> imagemagick<br />
<span class="kw3">cd</span> <span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>big<span class="sy0">/</span>images <span class="co0">#大图所在的目录</span><br />
<br />
<span class="co0">#创建小图对应的目录结构</span><br />
<span class="kw2">find</span> . <span class="re5">-type</span> d <span class="re5">-print</span> <span class="re5">-exec</span> <span class="kw2">mkdir</span> <span class="st_h">'../small/{}'</span> <span class="re5">-p</span> \;<br />
<br />
<span class="co0">#批量转换! 等比例缩小到320x320之内</span><br />
<span class="kw2">find</span> . <span class="re5">-type</span> f <span class="re5">-name</span> <span class="st_h">'*.jpg'</span> <span class="re5">-print</span> <span class="re5">-exec</span> \<br />
convert <span class="st_h">'{}'</span> <span class="re5">-resize</span> 320x320 <span class="st_h">'../small/{}'</span> \;</code></pre>

<p>这样小图都会按原先的目录结构，在上级目录的small目录出现了</p>

<p>其实<a href="http://www.imagemagick.org">imagemagick</a>是一个超级神器，上面只是它很简单的一个应用&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/584/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>让VIM与Ubuntu和睦相处</title>
		<link>http://q.pnq.cc/archives/575</link>
		<comments>http://q.pnq.cc/archives/575#comments</comments>
		<pubDate>Thu, 20 Oct 2011 06:04:29 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- linux -]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=575</guid>
		<description><![CDATA[Vim和Ubuntu都是我的好朋友，不过他们之间好像有点不和睦。在Ubuntu11.04下gvim的菜单不能集成进全局菜单条(global menu)，而在Ubuntu11.10下gvim打开之后会非常卡。需要调解一下 解决gvim在Ubuntu 11.04中菜单显示的问题 执行gvim时，gvim的菜单不能立刻显示出来。并且报错： ** (gvim:15150): WARNING **: Unable to register window with path &#8216;/com/canonical/menu/4200024&#8242;: Timeout was reached 解决方法是运行： echo 'alias gvim=&#34;env UBUNTU_MENUPROXY=0 gvim&#34;' &#62;&#62; ~/.bashrc source ~/.bashrc 解决gvim在Ubuntu 11.10中导致电脑很卡的问题 运行： echo 'alias gvim=&#34;gvim -f&#34;' &#62;&#62; ~/.bashrc source ~/.bashrc 解决提示“pixmap”的问题 如果终端中提示： (gvim:2353): Gtk-WARNING **: 无法在模块路径中找到主题引擎：“pixmap”， 解决方法是运行： sudo apt-get install gtk2-engines-pixbuf]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.vim.org">Vim</a>和<a href="http://www.ubuntu.com">Ubuntu</a>都是我的好朋友，不过他们之间好像有点不和睦。在<a href="http://www.ubuntu.com">Ubuntu</a>11.04下gvim的菜单不能集成进全局菜单条(global menu)，而在<a href="http://www.ubuntu.com">Ubuntu</a>11.10下gvim打开之后会非常卡。需要调解一下 <img src='http://q.pnq.cc/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>

<h2>解决gvim在<a href="http://www.ubuntu.com">Ubuntu</a> 11.04中菜单显示的问题</h2>

<p>执行gvim时，gvim的菜单不能立刻显示出来。并且报错：</p>

<blockquote>
  <p>** (gvim:15150): WARNING **: Unable to register window with path &#8216;/com/canonical/menu/4200024&#8242;: Timeout was reached</p>
</blockquote>

<p>解决方法是运行：</p>

<pre class="lang-bash"><code><span class="kw3">echo</span> <span class="st_h">'alias gvim=&quot;env UBUNTU_MENUPROXY=0 gvim&quot;'</span> <span class="sy0">&gt;&gt;</span> ~<span class="sy0">/</span>.bashrc<br />
<span class="kw3">source</span> ~<span class="sy0">/</span>.bashrc</code></pre>

<hr />

<h2>解决gvim在<a href="http://www.ubuntu.com">Ubuntu</a> 11.10中导致电脑很卡的问题</h2>

<p>运行：</p>

<pre class="lang-bash"><code><span class="kw3">echo</span> <span class="st_h">'alias gvim=&quot;gvim -f&quot;'</span> <span class="sy0">&gt;&gt;</span> ~<span class="sy0">/</span>.bashrc<br />
<span class="kw3">source</span> ~<span class="sy0">/</span>.bashrc</code></pre>

<hr />

<h2>解决提示“pixmap”的问题</h2>

<p>如果终端中提示：</p>

<blockquote>
  <p>(gvim:2353): Gtk-WARNING **: 无法在模块路径中找到主题引擎：“pixmap”，</p>
</blockquote>

<p>解决方法是运行：</p>

<pre class="lang-bash"><code><span class="kw2">sudo</span> <span class="kw2">apt-get</span> <span class="kw2">install</span> gtk2-engines-pixbuf</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/575/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>自动更新git目录</title>
		<link>http://q.pnq.cc/archives/565</link>
		<comments>http://q.pnq.cc/archives/565#comments</comments>
		<pubDate>Sat, 20 Aug 2011 10:57:36 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- linux -]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=565</guid>
		<description><![CDATA[假设我们有一批文件用Git在管理，然后在服务器上做了一个repo。团队成员先从服务器pull下来最新的版本，然后在本地修改并提交，最后push回服务器，这是很典型的应用场景。 假如现在需要服务器端收到客户端的push后，能自动更新repo目录里面的文件，听起来很简单，用钩子就可以了，不过还是遇到一些问题，好在最后在google帮助下搞定。 总结的步骤如下： 1.先在服务器端运行设置，接受提交 git config receive.denyCurrentBranch ignore 2.把以下内容保存为服务器端repo中的钩子文件（.git/hooks/post-receive） #!/bin/sh cd .. env -i git reset --hard 3.设置权限为可运行 chmod a+x post-receive 好了，这样每当服务器收到客户端的push，就会自动更新文件列表了]]></description>
			<content:encoded><![CDATA[<p>假设我们有一批文件用<a href="http://git-scm.com">Git</a>在管理，然后在服务器上做了一个repo。团队成员先从服务器pull下来最新的版本，然后在本地修改并提交，最后push回服务器，这是很典型的应用场景。</p>

<p>假如现在需要服务器端收到客户端的push后，能自动更新repo目录里面的文件，听起来很简单，用钩子就可以了，不过还是遇到一些问题，好在最后在google帮助下搞定。</p>

<p>总结的步骤如下：</p>

<p>1.先在服务器端运行设置，接受提交</p>

<pre><code>git config receive.denyCurrentBranch ignore
</code></pre>

<p>2.把以下内容保存为服务器端repo中的钩子文件（<strong>.git/hooks/post-receive</strong>）</p>

<pre class="lang-bash"><code><span class="co0">#!/bin/sh</span><br />
<span class="kw3">cd</span> ..<br />
<span class="kw2">env</span> <span class="re5">-i</span> git reset <span class="re5">--hard</span></code></pre>

<p>3.设置权限为可运行</p>

<pre><code>chmod a+x post-receive
</code></pre>

<p>好了，这样每当服务器收到客户端的push，就会自动更新文件列表了</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/565/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu下使用Array SSL VPN客户端连接VPN网络</title>
		<link>http://q.pnq.cc/archives/539</link>
		<comments>http://q.pnq.cc/archives/539#comments</comments>
		<pubDate>Fri, 01 Jul 2011 07:33:54 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- linux -]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[vpn]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=539</guid>
		<description><![CDATA[公司用的Array Networks提供的SSL VPN系统，vpn网页在Ubuntu下无法正常启动Java Applet。幸好得到了wenyue的指点，找到了方法。如果你也是Ubuntu系统，需要连接到Array SSL VPN，可以参考一下。 安装步骤 1.下载Array Networks提供的客户端程序 array_vpnc.bin sudo apt-get install libc6-i386 #64位系统也是这个包 wget http://q.pnq.cc/uploads/array_vpnc.bin chmod a+x array_vpnc.bin 2.下载这个小脚本到同个目录 #下载辅助脚本 wget http://q.pnq.cc/uploads/vpn-for-common.sh -O vpn.sh #里面会包含重要信息，我们不想别人随便访问 chmod 700 vpn.sh 3.修改vpn.sh中的配置，将vpn_host、user、key修改为你的配置 vpn_host=your_vpn_server user=your_user_name key=your_static_passwd #密码中不变的部分 使用方法： ./vpn.sh 然后根据提示输入，当看到这个提示时，就说明成功了： array_vpnc: VPN TUNNEL SUCCESSFUL! Have fun!]]></description>
			<content:encoded><![CDATA[<p>公司用的<a href="http://www.arraynetworks.com.cn/">Array Networks</a>提供的SSL VPN系统，vpn网页在Ubuntu下无法正常启动Java Applet。幸好得到了<a href="http://wenyue.me/blog/">wenyue</a>的指点，找到了方法。如果你也是Ubuntu系统，需要连接到Array SSL VPN，可以参考一下。</p>

<h2>安装步骤</h2>

<p>1.下载<a href="http://www.arraynetworks.com.cn/">Array Networks</a>提供的客户端程序 array_vpnc.bin</p>

<pre class="lang-bash"><code><span class="kw2">sudo</span> <span class="kw2">apt-get</span> <span class="kw2">install</span> libc6-i386 <span class="co0">#64位系统也是这个包</span><br />
<span class="kw2">wget</span> http:<span class="sy0">//</span>q.pnq.cc<span class="sy0">/</span>uploads<span class="sy0">/</span>array_vpnc.bin<br />
<span class="kw2">chmod</span> a+x array_vpnc.bin</code></pre>

<p>2.下载这个小脚本到同个目录</p>

<pre class="lang-bash"><code><span class="co0">#下载辅助脚本</span><br />
<span class="kw2">wget</span> http:<span class="sy0">//</span>q.pnq.cc<span class="sy0">/</span>uploads<span class="sy0">/</span>vpn-for-common.sh <span class="re5">-O</span> vpn.sh<br />
<span class="co0">#里面会包含重要信息，我们不想别人随便访问</span><br />
<span class="kw2">chmod</span> <span class="nu0">700</span> vpn.sh</code></pre>

<p>3.修改vpn.sh中的配置，将vpn_host、user、key修改为你的配置</p>

<pre class="lang-bash"><code><span class="re2">vpn_host</span>=your_vpn_server<br />
<span class="re2">user</span>=your_user_name<br />
<span class="re2">key</span>=your_static_passwd <span class="co0">#密码中不变的部分</span></code></pre>

<h2>使用方法：</h2>

<pre class="lang-bash"><code>.<span class="sy0">/</span>vpn.sh</code></pre>

<p>然后根据提示输入，当看到这个提示时，就说明成功了：</p>

<blockquote>
  <p>array_vpnc: VPN TUNNEL SUCCESSFUL!</p>
</blockquote>

<p>Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/539/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Flash真的适合做网站应用吗？</title>
		<link>http://q.pnq.cc/archives/496</link>
		<comments>http://q.pnq.cc/archives/496#comments</comments>
		<pubDate>Thu, 31 Mar 2011 14:24:27 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- Flash -]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[性能]]></category>
		<category><![CDATA[问题]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=496</guid>
		<description><![CDATA[两年前，我们开发了一套基于Flash的文件（主要是图片）上传RIA应用，提供给阿里巴巴的用户使用。如果你使用过Wordpress或flickr上传图片，你应该已经用过类似的产品。这个程序基于YUI Uploader开发，增加了一个实用的功能——在客户端先将图片缩小，再上传到服务器。用户用数码相机拍摄的照片往往有600万以上的像素，但产品图片放到阿里巴巴网站上显示，并不需要这么大的像素，通常等比例缩小到1024×1024之内就可以了。借助于Flash对图片先缩小再上传的技术，我们在没有增加服务器投入的情况下，将原先上传图片的尺寸限制由250KB/张提升到了5MB/张。同时，Flash上传还比传统HTML表单方式上传有更好的体验，例如可以多选一批文件同时上传、可以实时展示上传进度、选择文件时可以过滤非图片文件。 这个组件获得了很大的成功。上线后不久，阿里巴巴网站上用户的图片上传数量由日均1万张左右上升至日均15万张左右。但在这个上传应用投入应用的两年中，我们遇到了各种问题。 1. bug 在基于IE多标签浏览器中的伪沙箱问题就不说了，最严重的是cookie的问题。使用FileReference.upload的方式上传文件，http请求中附带的cookie信息不一定是当前浏览器进程的cookie，在Firefox、chrome等非IE浏览器中非常严重，可能传输的是IE中的cookie。即便是IE，也可能传输的cookie内容和当前页面的cookie记录不符合。这直接导致服务器端在收到文件之后的安全验证中失败。而对于阿里巴巴这样的大型网站，有比较成熟的java web框架，要去掉对cookie的依赖非常麻烦。于是结果就是，首先我们只有在用户使用IE系浏览器的时候才使用Flash上传，其次我们隔三岔五的还会收到使用IE的某些客户的投诉，在花费了大量的时间排查之后，我发现是由于cookie的问题导致上传失败。这个bug已经存在很多年，但是随着Flash从9升级到10，许多版本过去了，问题依然没有被解决。对于闭源的Flash，我们也帮不上忙。 2.性能 相对于现今数码相机的像素量，5MB的大小限制非常保守。但大于5M的时候，在一些低配置的电脑上，读取文件内容的时候就会发生浏览器假死现象。假死很容易导致浏览器崩溃，所以我们采取了保守的限制——5MB。 另外一个性能消耗是将BitmapData编码成JPEG文件的时候。Adobe提供了JPEGEncoder，但由于是Array实现的，所以性能是个问题。编码一个2880×2880的图片在一台中等配置的电脑上大约需要15秒时间。 我用Vector改写了这个类，时间缩短为3.5秒左右。使用Alchemy，时间进一步缩短到1.5秒左右。但还是不够安全，所以最后采用了异步Vector的方式，延长编码的时间，以保证程序的稳定性。（评测在这里） 3.图片质量 Flash内置的最好的图片缩小算法（用BitmapData.draw，并将smoothing参数设为true），在缩小图片的时候容易产生锯齿。因此我改写了Jacwright提供的缩小算法，图片质量的问题解决，但代价是性能又降低了一些。 4.安全限制 Flash10.0之后，增加了一个安全限制——当URLLoader以标准文件上传的方式发送POST请求的时候，需要由用户的UI操作（鼠标点击或按键事件）触发。因为我们对用户的图片做了处理，已经无法再通过FileReference上传，只能通过URLLoader。这个安全性限制规定每次发起一个上传文件的URLLoader请求，都必须让用户点击一下鼠标才可以。如果用户选择了20张图片，就要点击20次鼠标。这显然是无法接受的。因此我们放弃了用标准文件上传，采用普通post形式。代价是失去了对上传进度的跟踪，不知道文件上传的百分比；同时服务器端也需要改造。 改变 最近，我们做了一个决定：开发一个类似功能的ActiveX控件，替代Flash作为图片上传的主要解决方案。ActiveX的优势是性能，不足之处在于只能在Windows+IE浏览器中使用，但实际上我们的Flash上传目前也只能在IE中使用。Flash真的适合像阿里巴巴这样的网站使用吗？闭源和性能是Flash最大的问题。但在HTML5被广泛支持前，Flash和传统Ajax还是我们最主要的富客户端应用开发技术，相对于ActiveX、Silverlight、JavaFX、Gear等技术来说，Flash还是有安装率优势的。我们看到Adobe最近在新功能开发方面非常给力，值得称赞，但基础的功能的持续完善对开发者也同样重要。目前Flash依然是我们很重要的RIA技术，但是HTML5完全到来的那一天，现在很难说。]]></description>
			<content:encoded><![CDATA[<p>两年前，我们开发了一套基于Flash的文件（主要是图片）上传RIA应用，提供给阿里巴巴的用户使用。如果你使用过Wordpress或flickr上传图片，你应该已经用过类似的产品。这个程序基于<a title="YUI Uploader" href="http://developer.yahoo.com/yui/uploader/">YUI Uploader</a>开发，增加了一个实用的功能——在客户端先将图片缩小，再上传到服务器。用户用数码相机拍摄的照片往往有600万以上的像素，但产品图片放到阿里巴巴网站上显示，并不需要这么大的像素，通常等比例缩小到1024×1024之内就可以了。借助于Flash对图片先缩小再上传的技术，我们在没有增加服务器投入的情况下，将原先上传图片的尺寸限制由250KB/张提升到了5MB/张。同时，Flash上传还比传统HTML表单方式上传有更好的体验，例如可以多选一批文件同时上传、可以实时展示上传进度、选择文件时可以过滤非图片文件。</p>

<p><img class="alignnone size-full wp-image-512" style="margin: 5px; border: 1px solid black;" title="Screenshot" src="http://q.pnq.cc/wp-content/uploads/2011/03/Screenshot.png" alt="" width="782" height="352" /></p>

<p>这个组件获得了很大的成功。上线后不久，阿里巴巴网站上用户的图片上传数量由日均1万张左右上升至日均15万张左右。但在这个上传应用投入应用的两年中，我们遇到了各种问题。</p>

<h2>1. bug</h2>

<p><img class="alignnone size-medium wp-image-508" title="man062" src="http://q.pnq.cc/wp-content/uploads/2011/03/man062-500x494.jpg" alt="" width="500" height="494" /></p>

<p>在<a title="Flash在某些多标签浏览器中的“伪沙箱”问题" href="http://q.pnq.cc/archives/443">基于IE多标签浏览器中的伪沙箱问题</a>就不说了，最严重的是cookie的问题。使用FileReference.upload的方式上传文件，http请求中附带的cookie信息不一定是当前浏览器进程的cookie，在Firefox、chrome等非IE浏览器中非常严重，可能传输的是IE中的cookie。即便是IE，也可能传输的cookie内容和当前页面的cookie记录不符合。这直接导致服务器端在收到文件之后的安全验证中失败。而对于阿里巴巴这样的大型网站，有比较成熟的java web框架，要去掉对cookie的依赖非常麻烦。于是结果就是，首先我们只有在用户使用IE系浏览器的时候才使用Flash上传，其次我们隔三岔五的还会收到使用IE的某些客户的投诉，在花费了大量的时间排查之后，我发现是由于cookie的问题导致上传失败。<a href="http://cookbooks.adobe.com/post_Why_is_session_info__cookies__not_sent_when_upload-12029.html">这个bug</a>已经存在很多年，但是随着Flash从9升级到10，许多版本过去了，问题依然没有被解决。对于闭源的Flash，我们也帮不上忙。</p>

<h2>2.性能</h2>

<p><img class="alignnone size-medium wp-image-498" title="Mignight_Run_by_Orikon" src="http://q.pnq.cc/wp-content/uploads/2011/03/Mignight_Run_by_Orikon-500x340.jpg" alt="" width="500" height="340" /></p>

<p>相对于现今数码相机的像素量，5MB的大小限制非常保守。但大于5M的时候，在一些低配置的电脑上，读取文件内容的时候就会发生浏览器假死现象。假死很容易导致浏览器崩溃，所以我们采取了保守的限制——5MB。</p>

<p>另外一个性能消耗是将BitmapData编码成JPEG文件的时候。Adobe提供了JPEGEncoder，但由于是Array实现的，所以性能是个问题。编码一个2880×2880的图片在一台中等配置的电脑上大约需要15秒时间。</p>

<p>我用Vector改写了这个类，时间缩短为3.5秒左右。使用Alchemy，时间进一步缩短到1.5秒左右。但还是不够安全，所以最后采用了异步Vector的方式，延长编码的时间，以保证程序的稳定性。（评测在<a title="异步+Vector版本的JPEG编码器" href="http://q.pnq.cc/archives/307">这里</a>）</p>

<h2>3.图片质量</h2>

<p><img class="alignnone size-medium wp-image-505" title="iblrst00076625" src="http://q.pnq.cc/wp-content/uploads/2011/03/iblrst00076625-500x332.jpg" alt="" width="500" height="332" /></p>

<p>Flash内置的最好的图片缩小算法（用BitmapData.draw，并将smoothing参数设为true），在缩小图片的时候容易产生锯齿。因此我改写了<a href="http://jacwright.com/">Jacwright</a>提供的<a href="http://code.google.com/p/jacwright/source/browse/trunk/flash/jac/src/jac/image/ImageUtils.as">缩小算法</a>，图片质量的问题解决，但代价是性能又降低了一些。</p>

<h2>4.安全限制</h2>

<p><img class="alignnone size-medium wp-image-511" title="rad600-02833372s" src="http://q.pnq.cc/wp-content/uploads/2011/03/rad600-02833372s-500x333.jpg" alt="" width="500" height="333" /></p>

<p>Flash10.0之后，增加了一个安全限制——当URLLoader以标准文件上传的方式发送POST请求的时候，需要由用户的UI操作（鼠标点击或按键事件）触发。因为我们对用户的图片做了处理，已经无法再通过FileReference上传，只能通过URLLoader。这个安全性限制规定每次发起一个上传文件的URLLoader请求，都必须让用户点击一下鼠标才可以。如果用户选择了20张图片，就要点击20次鼠标。这显然是无法接受的。因此我们放弃了用标准文件上传，采用普通post形式。代价是失去了对上传进度的跟踪，不知道文件上传的百分比；同时服务器端也需要改造。</p>

<h2>改变</h2>

<p>最近，我们做了一个决定：开发一个类似功能的ActiveX控件，替代Flash作为图片上传的主要解决方案。ActiveX的优势是性能，不足之处在于只能在Windows+IE浏览器中使用，但实际上我们的Flash上传目前也只能在IE中使用。Flash真的适合像阿里巴巴这样的网站使用吗？闭源和性能是Flash最大的问题。但在HTML5被广泛支持前，Flash和传统Ajax还是我们最主要的富客户端应用开发技术，相对于ActiveX、Silverlight、JavaFX、Gear等技术来说，Flash还是有安装率优势的。我们看到Adobe最近在新功能开发方面非常给力，值得称赞，但基础的功能的持续完善对开发者也同样重要。目前Flash依然是我们很重要的RIA技术，但是HTML5完全到来的那一天，现在很难说。</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/496/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>如何一键启动Virtualbox虚拟机</title>
		<link>http://q.pnq.cc/archives/489</link>
		<comments>http://q.pnq.cc/archives/489#comments</comments>
		<pubDate>Fri, 25 Mar 2011 01:57:54 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- linux -]]></category>
		<category><![CDATA[virtualbox]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=489</guid>
		<description><![CDATA[现在用Ubuntu或者Mac的人越来越多了，但很多情况下还是离不开Windows，所以大多数人都是安装了Virtualbox，在VBox里面运行Windows虚拟机。 你是怎样启动Windows虚拟机的呢？是不是 1. 运行Virtualbox 2. 点选虚拟机的图标 3.点“启动” 那么可以考虑一下给单个虚拟机创建快捷方式，提高工作效率。别小看这点时间哦，每天节约下来的时间不可小视呢！ 在桌面/Dock上创建一个程序快捷方式: /usr/bin/VBoxManage startvm 虚拟机名称 例如我的虚拟机叫做XP，那么这个命令就是 /usr/bin/VBoxManage startvm XP 不同的系统可能VBoxManage所在的地方不一样，用这个命令查找VBoxManage所在路径： which VBoxManage 至于怎么创建快捷方式，可以参考网上的教程。这是我的Ubuntu上的效果： ps. 图标是在iconfinder找到的 &#160;]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-491" title="Screenshot-2" src="http://q.pnq.cc/wp-content/uploads/2011/03/Screenshot-2.jpg" alt="" width="865" height="136" />
现在用Ubuntu或者Mac的人越来越多了，但很多情况下还是离不开Windows，所以大多数人都是安装了Virtualbox，在VBox里面运行Windows虚拟机。</p>

<p>你是怎样启动Windows虚拟机的呢？是不是
1. 运行Virtualbox 2. 点选虚拟机的图标 3.点“启动”</p>

<p>那么可以考虑一下给单个虚拟机创建快捷方式，提高工作效率。别小看这点时间哦，每天节约下来的时间不可小视呢！</p>

<p>在桌面/Dock上创建一个程序快捷方式:
<code>/usr/bin/VBoxManage startvm 虚拟机名称</code></p>

<p>例如我的虚拟机叫做XP，那么这个命令就是
<code>/usr/bin/VBoxManage startvm XP</code></p>

<p>不同的系统可能VBoxManage所在的地方不一样，用这个命令查找VBoxManage所在路径：
<code>which VBoxManage</code></p>

<p>至于怎么创建快捷方式，可以参考网上的教程。这是我的Ubuntu上的效果：</p>

<p><img class="alignnone size-full wp-image-490" title="Virtualbox shortcut" src="http://q.pnq.cc/wp-content/uploads/2011/03/Screenshot-3.jpg" alt="" width="865" height="725" /></p>

<p>ps. 图标是在<a href="http://www.iconfinder.net" target="_blank">iconfinder</a>找到的</p>

<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/489/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>crontab无效的原因分析</title>
		<link>http://q.pnq.cc/archives/480</link>
		<comments>http://q.pnq.cc/archives/480#comments</comments>
		<pubDate>Thu, 24 Mar 2011 13:11:11 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- linux -]]></category>
		<category><![CDATA[crontab]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=480</guid>
		<description><![CDATA[有时候会发生这样的现象，命令是可以在shell中正常运行的，但添加到crontab中定时运行的时候，就发生一些异常的事情。（如果还不知道 Crontab 是什么的话，可以看一下这里先） 比如我今天在目录/home/ued66/asproj-builder 下写了一个 build-all.sh: svn up #更新代码 ./compile.rb --all &#62;&#62; ./log/run.log #编译，并将结果记录 在shell中运行这个命令是正常的： /home/ued66/asproj-builder/build-all.sh crontab中这样写： */5 * * * * /home/ued66/asproj-builder/build-all.sh (为了测试方便，设成每5分钟运行一次，实际是每天运行一次足矣） 虽然是同个命令，但是compile.rb却没有被正确调用。 经过调试，发现问题有两个： 1. 路径问题 既然用了相对路径，必须要把当前目录设置正确。把crontab写成这样： */5 * * * * cd /home/ued66/asproj-builder &#38;&#38; ./build-all.sh 2. 环境问题 compile.rb 是用ruby写的一个脚本，而我的ruby程序是用源码编译安装的，安装目录是/usr/local/ruby。compile.rb的第一行是 #!/usr/bin/env ruby 这是告诉shell使用ruby来执行这个脚本。但问题在于crontab运行的时候是没有加载用户环境变量的，“which ruby“运行结果为空也验证了这点。所以compile.rb不能被正确执行也很好理解了。 最后把build-all.sh写成这样，问题解决： #!/bin/sh svn up /usr/local/ruby/bin/ruby compile.rb --all &#62;&#62; ./log/run.log 看着程序自动运作起来，非常开心啊！]]></description>
			<content:encoded><![CDATA[<p>有时候会发生这样的现象，命令是可以在shell中正常运行的，但添加到crontab中定时运行的时候，就发生一些异常的事情。（如果还不知道 <a href="http://baike.baidu.com/view/1229061.html?fromTaglist">Crontab</a> 是什么的话，可以看一下<a href="http://baike.baidu.com/view/1229061.html?fromTaglist">这里</a>先）</p>

<p>比如我今天在目录/home/ued66/asproj-builder 下写了一个<em> build-all.sh</em>:
<code>svn up <span style="color: #888888;">#更新代码</span>
./compile.rb --all &gt;&gt; ./log/run.log <span style="color: #999999;">#编译，并将结果记录</span></code></p>

<p>在shell中运行这个命令是正常的：
<code>/home/ued66/asproj-builder/build-all.sh</code></p>

<p>crontab中这样写：
<code>*/5 * * * * /home/ued66/asproj-builder/build-all.sh</code>
(为了测试方便，设成每5分钟运行一次，实际是每天运行一次足矣）</p>

<p>虽然是同个命令，但是compile.rb却没有被正确调用。</p>

<p>经过调试，发现问题有两个：</p>

<p><strong>1. 路径问题</strong>
既然用了相对路径，必须要把当前目录设置正确。把crontab写成这样：
<code>*/5 * * * * cd /home/ued66/asproj-builder &amp;&amp; ./build-all.sh</code></p>

<p><strong>2. 环境问题</strong>
compile.rb 是用ruby写的一个脚本，而我的ruby程序是用源码编译安装的，安装目录是/usr/local/ruby。compile.rb的第一行是
<span style="color: #ff0000;"><code>#!/usr/bin/env ruby</code></span>
这是告诉shell使用ruby来执行这个脚本。但问题在于crontab运行的时候是没有加载用户环境变量的，“which ruby“运行结果为空也验证了这点。所以compile.rb不能被正确执行也很好理解了。</p>

<p>最后把build-all.sh写成这样，问题解决：
<code><span style="color: #999999;">#!/bin/sh</span>
svn up
<span style="color: #ff0000;"><strong>/usr/local/ruby/bin/ruby</strong></span> compile.rb --all &gt;&gt; ./log/run.log</code></p>

<p>看着程序自动运作起来，非常开心啊！</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/480/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Virtualbox 网络桥接不起作用？试试装增强功能</title>
		<link>http://q.pnq.cc/archives/474</link>
		<comments>http://q.pnq.cc/archives/474#comments</comments>
		<pubDate>Fri, 18 Mar 2011 13:47:07 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- Misc：其他 -]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=474</guid>
		<description><![CDATA[今天晚上在Ubuntu的服务器上用Virtualbox安装了一个Windows 7的虚拟机，一切都好，但在网络配置的时候遇到了问题。网卡选择桥接（Bridge）模式，运行时能（从DHCP服务器）得到ip地址，却无法上网。外部的计算机也访问不了该ip。 Google之，尝试了很多方法，都没有效果。 最后偶然发现，安装完增强功能包之后，居然桥接模式就正常了。进一步证明，这个增强功能包是必备的东东。 安装增强功能包，一开始是从Virtualbox菜单中安装，发现下载速度太慢。在apt里面搜到原来有个包：virtualbox-guest-additions，所以先执行这句： sudo apt-get install virtualbox-guest-additions 然后再到VB虚拟机里面点安装增强功能，可以节约一点时间。]]></description>
			<content:encoded><![CDATA[<p>今天晚上在Ubuntu的服务器上用Virtualbox安装了一个Windows 7的虚拟机，一切都好，但在网络配置的时候遇到了问题。网卡选择桥接（Bridge）模式，运行时能（从DHCP服务器）得到ip地址，却无法上网。外部的计算机也访问不了该ip。</p>

<p>Google之，尝试了很多方法，都没有效果。</p>

<p>最后偶然发现，安装完增强功能包之后，居然桥接模式就正常了。进一步证明，这个增强功能包是必备的东东。</p>

<p>安装增强功能包，一开始是从Virtualbox菜单中安装，发现下载速度太慢。在apt里面搜到原来有个包：virtualbox-guest-additions，所以先执行这句：
<code>sudo apt-get install virtualbox-guest-additions</code></p>

<p>然后再到VB虚拟机里面点安装增强功能，可以节约一点时间。</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/474/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Served from: q.pnq.cc @ 2012-05-22 01:15:11 by W3 Total Cache -->
