<?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>hackerzhou&#039;s bloghackerzhou&#039;s blog</title>
	<atom:link href="http://hackerzhou.me/feed" rel="self" type="application/rss+xml" />
	<link>http://hackerzhou.me</link>
	<description>Stay Hungry, Stay Foolish</description>
	<lastBuildDate>Fri, 13 Oct 2017 11:37:00 +0000</lastBuildDate>
	<language></language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>使用PowerShell脚本切换Windows7默认音频设备</title>
		<link>http://hackerzhou.me/2014/12/script-to-switch-default-audio-device.html</link>
		<comments>http://hackerzhou.me/2014/12/script-to-switch-default-audio-device.html#comments</comments>
		<pubDate>Sun, 07 Dec 2014 08:30:07 +0000</pubDate>
		<dc:creator>hackerzhou</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">https://www.hackerzhou.me/?p=1395</guid>
		<description>
			&lt;blockquote&gt;&lt;p&gt;有两年没写博客了，究其原因估计懒惰的成分比较大一些。今年发生的一些事打乱了我原本计划好的人生，在转折点上我还是选择重新做回追求生活品质的技术男。相信终会有和我三观match&amp;#038;志同道合的有缘人出现，理解并支持我表达爱的方式，相互扶持着走漫漫人生路。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;言归正传，本文笔者想分享的解决方案是想通过脚本来实现一键切换音频输出设备。随着大家对于音频设备的要求越来越高，一台计算机上往往接了不止一台音频输出设备（比如笔者这边就在3.5mm接口上接了一个Momentum，光纤接口上接了一个Philips HTL2160蓝牙声吧），那么如何简便地切换这些设备就成了一个问题。通常的做法需要在播放设备里手动把特定输出端标志成默认设备才行，无法避免的几次鼠标点击以及菜单选择显得并不那么方便。所以笔者就想，如果能用脚本来实现切换应该会很方便，而且甚至可以配合键盘的自定义按键来实现一键切换。&lt;/p&gt;
&lt;p&gt;查了若干资料，并没有发现有现成的API和注册表配置项可以调用（XP下似乎有一个Sound Mapper的注册表可以直接改目的设备的index）。不过出于习惯还是觉得这类配置属性应该是写在注册表HKEY_LOCAL_MACHINE或者HKEY_CURRENT_USER下的，仔细思索了下音量应该是全局共享的属性所以应该在HKEY_LOCAL_MACHINE下。于是开启注册表比对工具在手动设置前和设置后比对了下注册表，终于找到了那个键值路径：HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\{DEVICE_GUID}下的Role:0、Role:1和Role:2三个属性在设置之后会发生变化。以为找到方法了？Naive！微软才不会那么轻松就让我们找到隐藏关卡呢~&lt;/p&gt;
&lt;p&gt;让我们先来看看这个注册表节点的属性：&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&amp;#x5B;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\{158b3b6c-02c6-4c24-8900-2448fc78efd3}]&lt;br/&gt;&amp;quot;DeviceState&amp;quot;=dword:00000001&lt;br/&gt;&amp;quot;Role:0&amp;quot;=hex:de,07,0c,00,00,00,07,00,06,00,1b,00,29,00,c5,02&lt;br/&gt;&amp;quot;Role:1&amp;quot;=hex:de,07,0c,00,00,00,07,00,06,00,1b,00,29,00,c5,02&lt;br/&gt;&amp;quot;Role:2&amp;quot;=hex:de,07,0c,00,00,00,07,00,06,00,1b,00,29,00,c5,02&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;坑爹的二进制类型的值呐，而且每次手动更改之后值都与之前不一样。等等，每次更改都会变的值如果不是伪随机数/GUID那就是————时间了！让我们先来解读下这个16字节的二进制数据。顺便普及下基础编程知识，每个0x00这样的数字都代表了一个十六进制数字，称为1个byte；两个byte是short；四个byte是int。而且除了少部分操作系统之外我们用的大都是小端法（little-endian）来存储二进制数据，即低位排在最前。&lt;br /&gt;
那么这个二进制可以被解读为：&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;0x07DE = 2014 (dec) //Year&lt;br/&gt;0x000C = 12   (dec) //Month&lt;br/&gt;0x0000 = 0    (dec) //DayOfWeek&lt;br/&gt;0x0007 = 7    (dec) //Day&lt;br/&gt;0x0006 = 6    (dec) //Hour&lt;br/&gt;0x001B = 27   (dec) //Minute&lt;br/&gt;0x0029 = 41   (dec) //Second&lt;br/&gt;0x02C5 = 709  (dec) //Millisecond&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;看看我们发现了什么~看起来是个日期+时间，根据和当前时间的比对得出用的是UTC时间。第三个short是0不太好判断，一开始只是猜测是DayOfWeek，不过可以通过更改系统日期来做个快速的确认。鉴于我们解读出来的数据，可以做个大胆的推测：Windows自带的控制程序把当前系统时间写进不同输出设备下的Role:[0-2]属性，拥有最近的时间戳的就拥有了默认优先权。又做了次实验，似乎Role:0以及Role:1是用来作为默认设备，而Role:2是作为默认通信设备。至此，似乎解决方案已经呼之欲出了。祭出Windows下的脚本语言PowerShell来完成开发，因为PowerShell可以用脚本语言的方式直接调用.NET的API比较方便些。&lt;/p&gt;
&lt;p&gt;写完之后一运行，出现错误“Set-ItemProperty : 不允许所请求的注册表访问权。”这是什么鬼，搜了一下发现是不符合注册表的ACL的缘故，简单的来说就是注册表里的节点都是有权限限制的，谁可以读谁可以写都能单独限制。这时候就要用第二个workaround了：右击Device GUID那个节点，选择权限。&lt;br /&gt;
&lt;a href="https://www.hackerzhou.me/wp-content/uploads/2014/12/switch_device1.png"&gt;&lt;img decoding="async" src="https://www.hackerzhou.me/wp-content/uploads/2014/12/switch_device1.png" alt="switch_device1" height="350" class="size-full wp-image-1402" /&gt;&lt;/a&gt; &lt;a href="https://www.hackerzhou.me/wp-content/uploads/2014/12/switch_device2.png"&gt;&lt;img decoding="async" src="https://www.hackerzhou.me/wp-content/uploads/2014/12/switch_device2.png" alt="switch_device2" height="350" class="size-full wp-image-1404" /&gt;&lt;/a&gt;&lt;br /&gt;
发现在这个页面上并不能给Administrators组或者当前管理员帐号分配系统权限，是因为Windows系统还有一个奇葩的内建帐号SYSTEM存在，进入“高级”把所有者从SYSTEM手里抢回来就可以了。给当前用户或者用户组赋了权限之后别忘把SYSTEM也给加上，因为SYSTEM现在不是Owner了，不过不加有没有side effect笔者也没有进一步尝试。&lt;/p&gt;
&lt;p&gt;至此脚本终于可以顺利执行了，但似乎还有个小问题，改了注册表之后在界面上可以看到默认设备变了，但实际音频并没有做切换。想想也是，注册表只是持久化下来的配置，我们一般写程序的时候需要维护一个in-memory的状态值，但我们这是在进程外修改，在不知道hook和如何触发回调函数的时候最简单粗暴的方法就是restart那个进程让它重新初始化。果然，在重启了audiosrv服务之后音频果然切换了~大功告成！&lt;/p&gt;
&lt;p&gt;依照惯例贴下实现的代码：&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;#&lt;br/&gt;# Script to switch default audio device on Windows 7&lt;br/&gt;# Author: hackerzhou&lt;br/&gt;# Date:   2014/12/07&lt;br/&gt;#&lt;br/&gt;&lt;br/&gt;if ($args.Length -ne 1) {&lt;br/&gt;  Write-Host &amp;quot;Usage: powershell.exe -File SwitchAudioDevice.ps1 {DEVICE GUID}&amp;quot;&lt;br/&gt;  Exit 1&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;$device = $args&amp;#x5B;0]&lt;br/&gt;function WriteDateBinary($dateBinary, $value, $index) {&lt;br/&gt;  $shortValue = &amp;#x5B;UInt16]$value&lt;br/&gt;  $tmp = &amp;#x5B;BitConverter]::GetBytes($shortValue)&lt;br/&gt;  &amp;#x5B;Array]::Copy($tmp, 0, $dateBinary, $index, 2)&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;$currentUtcDateTime = (Get-Date).ToUniversalTime()&lt;br/&gt;$dateBinary = New-Object Byte&amp;#x5B;] 16&lt;br/&gt;WriteDateBinary $dateBinary $currentUtcDateTime.Year         0&lt;br/&gt;WriteDateBinary $dateBinary $currentUtcDateTime.Month        2&lt;br/&gt;WriteDateBinary $dateBinary $currentUtcDateTime.DayOfWeek    4&lt;br/&gt;WriteDateBinary $dateBinary $currentUtcDateTime.Day          6&lt;br/&gt;WriteDateBinary $dateBinary $currentUtcDateTime.Hour         8&lt;br/&gt;WriteDateBinary $dateBinary $currentUtcDateTime.Minute      10&lt;br/&gt;WriteDateBinary $dateBinary $currentUtcDateTime.Second      12&lt;br/&gt;WriteDateBinary $dateBinary $currentUtcDateTime.Millisecond 14&lt;br/&gt;&lt;br/&gt;$regPath = &amp;quot;Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\$device&amp;quot;&lt;br/&gt;Set-ItemProperty $regPath &amp;quot;Role:0&amp;quot; $dateBinary -type Binary&lt;br/&gt;Set-ItemProperty $regPath &amp;quot;Role:1&amp;quot; $dateBinary -type Binary&lt;br/&gt;Set-ItemProperty $regPath &amp;quot;Role:2&amp;quot; $dateBinary -type Binary&lt;br/&gt;&lt;br/&gt;Restart-Service audiosrv&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;最后，晒下我现在的多媒体工作环境，Windows台式机/MacBook Pro/&lt;a href="http://www1.ap.dell.com/cn/zh/epub/Dell-Peripherals/monitor-dell-2209wa/pd.aspx?refid=monitor-dell-2209wa&amp;#038;s=epub"&gt;Dell 2209WA&lt;/a&gt;/&lt;a href="http://accessories.ap.dell.com/sna/productdetail.aspx?c=cn&amp;#038;cs=cnbsd1&amp;#038;l=zh&amp;#038;s=bsd&amp;#038;sku=391-10089"&gt;Dell U2413&lt;/a&gt;/&lt;a href="http://www.philips.com.cn/c/soundbars/soundbar-speaker-htl2160_93/prd/"&gt;Philips HTL2160&lt;/a&gt;/&lt;a href="http://momentum.sennheiser.com.cn/"&gt;Momentum&lt;/a&gt;/AIX RS-8A/&lt;a href="http://www.icon-global.com/Audio+Interface_Recording_MicU.htm"&gt;iCON MicU&lt;/a&gt;/11TB NAS(&lt;a href="http://www8.hp.com/us/en/products/proliant-servers/product-detail.html?oid=5379860"&gt;HP MicroServer Gen8&lt;/a&gt;)。低音炮占地方而且碍眼后来被我移到显示器背后了，反正人耳对低音来源方位不敏感。&lt;br /&gt;
&lt;a href="https://www.hackerzhou.me/wp-content/uploads/2014/12/DSC04023.jpg"&gt;&lt;img decoding="async" src="https://www.hackerzhou.me/wp-content/uploads/2014/12/DSC04023.jpg" alt="DSC04023" width="400" class="size-full wp-image-1411" /&gt;&lt;/a&gt; &lt;a href="https://www.hackerzhou.me/wp-content/uploads/2014/12/DSC04031.jpg"&gt;&lt;img decoding="async" src="https://www.hackerzhou.me/wp-content/uploads/2014/12/DSC04031.jpg" alt="DSC04031" width="400" class="size-full wp-image-1412" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;br /&gt;&lt;p&gt;&lt;small&gt;&lt;i&gt;Post Tags: &lt;a href="http://hackerzhou.me/tag/net" rel="tag"&gt;.NET&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/powershell" rel="tag"&gt;PowerShell&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/windows" rel="tag"&gt;Windows&lt;/a&gt;&lt;/i&gt;&lt;/small&gt;&lt;hr /&gt;&lt;center&gt;&lt;small&gt;本文基于 &lt;a href="http://creativecommons.org/licenses/by/2.5/cn/"&gt;署名 2.5 中国大陆&lt;/a&gt; 许可协议发布，欢迎转载，演绎或用于商业目的，但是必须保留本文的署名 &lt;a href="http://hackerzhou.me/author/admin"&gt;hackerzhou&lt;/a&gt; 并包含 &lt;a href="http://hackerzhou.me/2014/12/script-to-switch-default-audio-device.html"&gt;原文链接&lt;/a&gt;。&lt;br /&gt;Copyright &amp;copy; 2026 &lt;a href="http://hackerzhou.me"&gt;hackerzhou&amp;#039;s blog&lt;/a&gt;  2009-2026&lt;/small&gt;&lt;/center&gt;&lt;/p&gt;		</description>
		<wfw:commentRss>http://hackerzhou.me/2014/12/script-to-switch-default-audio-device.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>密码保护：通过UUID在vSphere虚拟机内外识别硬盘</title>
		<link>http://hackerzhou.me/2012/11/how-to-recognize-disk-inside-and-outside-vm.html</link>
		<comments>http://hackerzhou.me/2012/11/how-to-recognize-disk-inside-and-outside-vm.html#comments</comments>
		<pubDate>Mon, 26 Nov 2012 14:07:59 +0000</pubDate>
		<dc:creator>hackerzhou</dc:creator>
				<category><![CDATA[虚拟化]]></category>
		<category><![CDATA[disk uuid]]></category>
		<category><![CDATA[VMware]]></category>
		<category><![CDATA[vSphere]]></category>

		<guid isPermaLink="false">https://www.hackerzhou.me/?p=1338</guid>
		<description>
			&lt;p&gt;很久没有跟新博客了，工作比较忙是一方面原因，另一方面，最近也没有足够多能share的干货。这次写写最近查资料发现的一个比较有用的解决方案，希望能帮助到有着同样困惑的朋友们。简单介绍下应用场景：开发基于虚拟化IaaS的一些应用就免不了要跟虚拟机(VM)打交道，因为VM逻辑上独立于宿主机(host)，两者之间的交互就成了一个问题，本文介绍的就是在vSphere环境下VM和host之间如何准确识别硬盘，希望能对同样基于VMware vSphere平台做开发的朋友们一点帮助和启发。&lt;/p&gt;
&lt;h2&gt;如何标识硬盘&lt;/h2&gt;
&lt;p&gt;在物理机上我们把硬盘插在一条条数据线上，数据线被接到控制器总线上。IaaS这一层把对基础硬件这一层给池化，因此也提供了一系列对硬件操作的API，增加/删除设备等等。和在物理环境下一样，增加虚拟硬盘也需要指定对应的总线号和在总线上的位置，看起来这个总线号（类似X:Y，X是总线编号，Y是在总线上的unit号）可以成为内外部统一的标识符了。不过，不要too young too simple的以为真相会是那么简单哟。&lt;/p&gt;
&lt;p&gt;在Linux中使用总线编号来查询磁盘主要有两种方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在/sys/class/scsi_disk下面有诸如2:0:1:0之类的地址，见下图。&lt;br /&gt;
&lt;a href="https://www.hackerzhou.me/wp-content/uploads/2012/11/linux2.png"&gt;&lt;img decoding="async" class="size-full wp-image-1355" title="linux2" src="https://www.hackerzhou.me/wp-content/uploads/2012/11/linux2.png" alt="" width="410" srcset="http://hackerzhou.me/wp-content/uploads/2012/11/linux2.png 456w, http://hackerzhou.me/wp-content/uploads/2012/11/linux2-300x24.png 300w" sizes="(max-width: 456px) 100vw, 456px" /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;在/dev/disk/by-path下有一堆名字包含总线地址的符号链接。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;让我们来看看使用总线位置标识X:Y来识别硬盘的问题：在Linux里，总线编号X其实取决于kernel module加载的顺序。使用dmesg命令查看日志可以发现，对应的总线控制器驱动的行为是：每个驱动在初始化的时候会扫描总线，看看有哪个总线是匹配的，然后拿到一个bus id来标识这条总线，这个bus id也就是我们的总线编号X。如果IDE总线驱动第一个被加载，然后再加载SCSI总线驱动，那么IDE总线就会拿到bus id 0，而SCSI总线就只能从1开始了。而且在虚拟化环境里SCSI总线也有不同的类别（LSIlogic，PVSCI等），对应不同的kernel module，因此不同类型的SCSI总线之间也会产生总线编号不确定的问题。&lt;/p&gt;
&lt;p&gt;那是不是可以通过控制kernel module的方法来人为干预SCSI总线号呢？楼主用实践证明了这是个不靠谱stupid idea，有如下几个原因：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;每个发行版修改kernel module加载顺序的方法不尽相同，RHEL 5.x就比较容易，重新编译下initrd，使用mkinitrd的&amp;#8211;with参数定义module加载顺序就可以了。而RHEL 6.x由于使用了initramfs用老方法就不顶用了，尝试了很久发现有一个hack的方法：修改grub.conf，使用内核参数rdloaddriver（强制加载）和rdblacklist（强制不加载）来控制启动顺序，当然这是很不推荐的做法。&lt;/li&gt;
&lt;li&gt;对于某些奇葩的系统，比如RHEL 6.0/Oracle Linux 6.0，即使修改grub.conf也不顶用，启动的时候module加载顺序会突变，暂时还不清楚突变的根本原因，但可能是一个bug，毕竟在之后的系统中都没有这个问题。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;那听上去是不是没有什么好办法了？要没有好办法楼主也不会废话那么多失败的例子了。目前看来靠谱的方法是使用UUID来在虚拟机内外唯一标识磁盘，用法也很简单。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Disk UUID在vSphere上默认是关闭的，需要通过在VM上设置参数disk.enableUUID=TRUE打开，如下图所示，注意因为configuration parameters实际上是被写入vmx文件的，故无法在开机情况下修改。理论上应该也可以通过修改host上面的/etc/vmware/config来实现host level全局的修改，这样就无需一个一个VM单独进行设置了。&lt;br /&gt;
&lt;a href="https://www.hackerzhou.me/wp-content/uploads/2012/11/1.png"&gt;&lt;img decoding="async" class="wp-image-1350" title="set disk.enableUUID" src="https://www.hackerzhou.me/wp-content/uploads/2012/11/1.png" alt="" width="500" srcset="http://hackerzhou.me/wp-content/uploads/2012/11/1.png 608w, http://hackerzhou.me/wp-content/uploads/2012/11/1-300x241.png 300w" sizes="(max-width: 608px) 100vw, 608px" /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;在目标机器上安装VMware Tools。&lt;/li&gt;
&lt;li&gt;在VM外可以使用vSphere的MBO（Managed Object Browser）来查看磁盘的UUID，找到VM-&amp;gt;config-&amp;gt;hardware-&amp;gt;device-&amp;gt;#DEVICE_KEY#-&amp;gt;backing，如下图所示。当然通过API也可以查询甚至修改磁盘的UUID。&lt;br /&gt;
&lt;a href="https://www.hackerzhou.me/wp-content/uploads/2012/11/2.png"&gt;&lt;img decoding="async" class="alignnone wp-image-1357" title="MOB" src="https://www.hackerzhou.me/wp-content/uploads/2012/11/2.png" alt="" width="650" srcset="http://hackerzhou.me/wp-content/uploads/2012/11/2.png 806w, http://hackerzhou.me/wp-content/uploads/2012/11/2-300x245.png 300w" sizes="(max-width: 806px) 100vw, 806px" /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;启用disk UUID并且安装了VMware Tools之后，可以在VM里面根据UUID来查询了。&lt;br /&gt;
a) Linux可以在/dev/disk/by-id下找到一系列名字包含UUID的符号链接，target就是device node，类似/dev/sda，/dev/sdb之类的，可以使用readlink命令来得到符号链接的target。注意这里是by-id不是by-uuid，by-id这个目录只有在设置了disk.enableUUID之后才会出现。如下图所示，可以看到有by-id/by-path/by-uuid三个目录，by-path对应的就是上文介绍的使用SCSI总线地址来进行磁盘查找的方法。&lt;br /&gt;
&lt;a href="https://www.hackerzhou.me/wp-content/uploads/2012/11/linux.png"&gt;&lt;img decoding="async" class="size-full wp-image-1353" title="linux" src="https://www.hackerzhou.me/wp-content/uploads/2012/11/linux.png" alt="" width="580" srcset="http://hackerzhou.me/wp-content/uploads/2012/11/linux.png 693w, http://hackerzhou.me/wp-content/uploads/2012/11/linux-300x222.png 300w" sizes="(max-width: 693px) 100vw, 693px" /&gt;&lt;/a&gt;&lt;br /&gt;
b) Windows可以使用Powershell命令：Get-WmiObject Win32_PhysicalMedia | where {$_.serialNumber -eq &amp;#8216;#UUID#&amp;#8217;} 来查询对应的磁盘，查到是第几块磁盘之后就可以使用diskpart来进行磁盘初始化。如下图所示，PHYSICALDRIVE0就是指第0块硬盘。&lt;br /&gt;
&lt;a href="https://www.hackerzhou.me/wp-content/uploads/2012/11/win.png"&gt;&lt;img decoding="async" class="alignnone wp-image-1359" title="win" src="https://www.hackerzhou.me/wp-content/uploads/2012/11/win.png" alt="" width="720" srcset="http://hackerzhou.me/wp-content/uploads/2012/11/win.png 962w, http://hackerzhou.me/wp-content/uploads/2012/11/win-300x143.png 300w" sizes="(max-width: 962px) 100vw, 962px" /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;注意做Linked Clone也不会改变磁盘的UUID，这个UUID是记录在root vmdk文件中的，登录到ESXi上去可以用vi打开vmdk描述文件查看到。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;开机状态检测磁盘的增加/变更&lt;/h2&gt;
&lt;p&gt;虚拟化环境拥有很多物理环境中做不到或者是很难做到的功能，比如在开机状态下热增加磁盘，计算资源（参考&lt;a href="https://www.hackerzhou.me/2012/05/vmware-hot-add-cpu-memory-feature-notes.html"&gt;VMware vSphere hot-add CPU/memory学习笔记&lt;/a&gt;）等，算是先天优势而不是屌丝逆袭。现在各种操作系统也针对虚拟化环境做了不少优化，比如在Windows中热增加的磁盘能直接被识别出来。而Linux下就需要执行下面命令来重新扫描某个SCSI总线上的磁盘设备：&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;# {scsi_host_id}是系统上识别出来的bus id&lt;br/&gt;echo &amp;quot;- - -&amp;quot; &amp;gt; /sys/class/scsi_host/host{scsi_host_id}/scan&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;如果只是在外部修改磁盘大小，在Linux下也需要执行命令才能够使得guest系统正确识别新的size：&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;# {device_name}是逻辑设备号，比如sda，sdb。。。&lt;br/&gt;echo 1 &amp;gt; /sys/block/{device_name}/device/rescan&lt;br/&gt;# 然后你可以决定是否用resize2fs来调整文件系统大小&lt;br/&gt;resize2fs /dev/{device_name}&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;对于在虚拟机内外准确识别硬盘以及在开机状态下识别新增磁盘以及磁盘容量变化的问题就介绍到这里，相信大家对vSphere下的disk操作有了一些新的理解。由于水平有限，有些地方可能有些纰漏，敬请谅解。&lt;/p&gt;
&lt;br /&gt;&lt;p&gt;&lt;small&gt;&lt;i&gt;Post Tags: &lt;a href="http://hackerzhou.me/tag/disk-uuid" rel="tag"&gt;disk uuid&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/vmware" rel="tag"&gt;VMware&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/vsphere" rel="tag"&gt;vSphere&lt;/a&gt;&lt;/i&gt;&lt;/small&gt;&lt;hr /&gt;&lt;center&gt;&lt;small&gt;本文基于 &lt;a href="http://creativecommons.org/licenses/by/2.5/cn/"&gt;署名 2.5 中国大陆&lt;/a&gt; 许可协议发布，欢迎转载，演绎或用于商业目的，但是必须保留本文的署名 &lt;a href="http://hackerzhou.me/author/admin"&gt;hackerzhou&lt;/a&gt; 并包含 &lt;a href="http://hackerzhou.me/2012/11/how-to-recognize-disk-inside-and-outside-vm.html"&gt;原文链接&lt;/a&gt;。&lt;br /&gt;Copyright &amp;copy; 2026 &lt;a href="http://hackerzhou.me"&gt;hackerzhou&amp;#039;s blog&lt;/a&gt;  2009-2026&lt;/small&gt;&lt;/center&gt;&lt;/p&gt;		</description>
		<wfw:commentRss>http://hackerzhou.me/2012/11/how-to-recognize-disk-inside-and-outside-vm.html/feed</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>VMware vSphere hot-add CPU/memory学习笔记</title>
		<link>http://hackerzhou.me/2012/05/vmware-hot-add-cpu-memory-feature-notes.html</link>
		<comments>http://hackerzhou.me/2012/05/vmware-hot-add-cpu-memory-feature-notes.html#comments</comments>
		<pubDate>Sat, 05 May 2012 04:34:33 +0000</pubDate>
		<dc:creator>hackerzhou</dc:creator>
				<category><![CDATA[虚拟化]]></category>
		<category><![CDATA[hot-add]]></category>
		<category><![CDATA[VMware]]></category>
		<category><![CDATA[vSphere]]></category>

		<guid isPermaLink="false">https://www.hackerzhou.me/?p=1302</guid>
		<description>
			&lt;p&gt;前段时间接触VMware vSphere的hot-add/plug功能，感觉很炫，虚拟机跑着跑着多出来几个CPU和几G的内存。其实还远远不止这些，还可以热插网卡和硬盘等等，hot-add/plug为虚拟化管理员提供了在不允许停机的生产环境中仍然可以动态添加设备的方法。本文主要介绍下CPU和memory的hot-add/plug、如何让guest OS识别新配置以及一些目前已知的问题，希望给VMware虚拟化社区贡献一份力，同时希望能抛砖引玉，让更多的虚拟化爱好者们能分享各自的经验。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.vmware.com/support/vsphere5/doc/vsphere-esx-vcenter-server-50-release-notes.html" target="_blank"&gt;vSphere Release Notes&lt;/a&gt;以及vSphere Client中使用hot-add memory和hot-plug CPU的措辞，不过我觉得说成广义的hot-add也并无不可，因此下文用hot-add来指代hot-add/plug。&lt;/p&gt;
&lt;h3&gt;Hot-add可以抽象成三个步骤：&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;打开VM的hot-add选项（hot-add 功能默认不会打开）。右击一个已经关机的VM-&amp;gt;&amp;#8221;Edit Settings&amp;#8221;-&amp;gt;&amp;#8221;Options&amp;#8221;-&amp;gt;&amp;#8221;Memory/CPU Hot-pluging&amp;#8221;，打开memory和CPU的hot-add/plug。具体的操作可以参考有图示的教程 &lt;a href="http://www.petri.co.il/vsphere-hot-add-memory-and-cpu.htm" target="_blank"&gt;Using vSphere Hot-Add to Dynamically Add CPU and RAM&lt;/a&gt;，下图拷贝自上述教程。&lt;a href="https://www.hackerzhou.me/wp-content/uploads/2012/05/07-enable-hot-plug-hot-add.png"&gt;&lt;img fetchpriority="high" decoding="async" class="aligncenter size-full wp-image-1312" title="来自 http://www.petri.co.il/wp-content/uploads/07-enable-hot-plug-hot-add.png" src="https://www.hackerzhou.me/wp-content/uploads/2012/05/07-enable-hot-plug-hot-add.png" alt="" width="549" height="487" srcset="http://hackerzhou.me/wp-content/uploads/2012/05/07-enable-hot-plug-hot-add.png 549w, http://hackerzhou.me/wp-content/uploads/2012/05/07-enable-hot-plug-hot-add-300x266.png 300w" sizes="(max-width: 549px) 100vw, 549px" /&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/li&gt;
&lt;li style="text-align: left;"&gt;在VM上触发hot-add。开启了VM的hot-add之后，在VM开机状态下进入&amp;#8221;Edit Settings&amp;#8221;会发现内存和CPU都是可配置的了。配置好之后vSphere会通知guest OS它的设备发生了改变，下图拷贝自上述教程。。&lt;a href="https://www.hackerzhou.me/wp-content/uploads/2012/05/11-changing-memory-dynamically-using-hot-add.png"&gt;&lt;img decoding="async" class="aligncenter size-full wp-image-1313" title="来自 http://www.petri.co.il/wp-content/uploads/11-changing-memory-dynamically-using-hot-add.png" src="https://www.hackerzhou.me/wp-content/uploads/2012/05/11-changing-memory-dynamically-using-hot-add.png" alt="" width="553" height="485" srcset="http://hackerzhou.me/wp-content/uploads/2012/05/11-changing-memory-dynamically-using-hot-add.png 553w, http://hackerzhou.me/wp-content/uploads/2012/05/11-changing-memory-dynamically-using-hot-add-300x263.png 300w" sizes="(max-width: 553px) 100vw, 553px" /&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;让运行在VM里的guest OS识别出新设备。Windows一般能自动识别出并使用新的memory和CPU，但在Linux下就需要我们用脚本让系统使用新配置。VMware Knowledge Base中有一篇&lt;br /&gt;
&lt;a href="http://kb.vmware.com/kb/1012764" target="_blank"&gt; Hot adding memory in Linux&lt;/a&gt;，对CPU的操作也很类似。有自动化需要的可以用这两个脚本：&lt;a href="http://communities.vmware.com/servlet/JiveServlet/download/10492-7-26611/online_hotplug_memory.sh"&gt;online_hotplug_memory.sh&lt;/a&gt; 和 &lt;a href="http://communities.vmware.com/servlet/JiveServlet/download/10493-2-26560/online_hotplug_cpu.sh" target="_blank"&gt;online_hotplug_cpu.sh&lt;/a&gt;，两个脚本都不难理解，无非就是往识别出但是没有online的CPU和memory的state文件里面写标识符让系统online下设备而已。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;局限性（根据个人经验和参考文档）：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Hot-add memory的数量有严格的限制：&lt;br /&gt;
1）新memory大小必须是128的整数倍。&lt;br /&gt;
2）如果hot-add前的memory小于3G，最多只能hot-add到3G。&lt;br /&gt;
3）如果hot-add前的memory等于3G，则不能hot-add任何memory。&lt;br /&gt;
4）如果hot-add前的memory大于3G，最多能hot-add 原先memory的16倍，但不能超过 hardware limit（对VM version 7来说最多到255G，对VM version8来说1011G）。简单的来说就是 limit=min(old_memory * 16, vm_version_7 ? 255G:1011G)&lt;/li&gt;
&lt;li&gt;对于version 7的VM，hot-add CPU只能在core为1的情况下对socket进行增加。而VM version8可以在core不为1的情况下添加socket。&lt;/li&gt;
&lt;li&gt;Hot-add 功能和VMware Fault Tolerance（FT）功能互斥，不能同时使用。&lt;/li&gt;
&lt;li&gt;开启hot-add必须在VM关闭的状态下进行，其实通过往vmx文件里写&amp;#8221;mem.hotadd&amp;#8221;和&amp;#8221;vcpu.hotadd&amp;#8221;两个属性一样内开启hot-add。&lt;/li&gt;
&lt;li&gt;Hot-add成功与否依赖guest OS是否支持hot-add。Hot-add之后guest OS必须得能识别并且使用新设备，不然hot-add只不过是在VM层面上进行了硬件的调整，操作系统内部并不识别。&lt;br /&gt;
Windows下的支持性可以参考 &lt;a href="http://www.boche.net/blog/index.php/2009/05/10/vsphere-memory-hot-add-cpu-hot-plug/" target="_blank"&gt;vSphere Memory Hot Add/CPU Hot Plug&lt;/a&gt;&lt;br /&gt;
Linux下的支持性可以参考 &lt;a href="http://kb.parallels.com/en/111216 " target="_blank"&gt;CPU and RAM hotplug support by PSBM 5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Hot-add 功能只在vSphere Advanced、Enterprise、Enterprise Plus version 上才能被开启，也就是说只有交了钱才能享受到高端功能。&lt;/li&gt;
&lt;li&gt;Hot-add memory之后可能会导致数秒的CPU 100%使用率。&lt;/li&gt;
&lt;li&gt;内核版本小于2.6.38的Linux有kernel bug，会导致有时候guest OS无法识别新加上的内存。根据 &lt;a href="http://kb.parallels.com/en/111279" target="_blank"&gt;Hot-plugged memory cannot be initialized in a Linux VM&lt;/a&gt; 这篇kb中的描述来看，原内存越小越容易导致无法添加成功。在试验中验证了这点，并且发现原内存在hot-add前使用率越高，新内存就越无法成功被识别。要想workaround，别无他法，只能使用尽可能新的内核版本。&lt;br /&gt;
比如在guest OS是SLSE 11 SP1（内核2.6.32）的情况下，512M内存无负载可以hot-add成功（但仍有接近128M内存无法被识别），但512M内存跑个程序消耗70%的内存就无法识别hot-add上的内存（哪怕直接hot-add到3G也是一兆都认不出）。&lt;br /&gt;
而在 Ubuntu 11.04（内核2.6.38）中，空负载的情况下可以识别出全部hot-add上的内存，不会丢失128M；在负载较大的情况下仍然可以识别出大部分hot-add上的内存（仍然会丢失128M）。&lt;/li&gt;
&lt;li&gt;另有一篇文章也分析了hot-add 功能：&lt;a href="http://searchvmware.techtarget.com/tip/VMware-vSphere-hot-add-RAM-and-hot-plug-CPU-Not-so-hot-but-still-cool" target="_blank"&gt;VMware vSphere hot-add RAM and hot-plug CPU: Not so &amp;#8216;hot,&amp;#8217; but still cool&lt;/a&gt;，有兴趣的同学也可以看看。&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;&lt;p&gt;&lt;small&gt;&lt;i&gt;Post Tags: &lt;a href="http://hackerzhou.me/tag/hot-add" rel="tag"&gt;hot-add&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/vmware" rel="tag"&gt;VMware&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/vsphere" rel="tag"&gt;vSphere&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/%e8%99%9a%e6%8b%9f%e5%8c%96" rel="tag"&gt;虚拟化&lt;/a&gt;&lt;/i&gt;&lt;/small&gt;&lt;hr /&gt;&lt;center&gt;&lt;small&gt;本文基于 &lt;a href="http://creativecommons.org/licenses/by/2.5/cn/"&gt;署名 2.5 中国大陆&lt;/a&gt; 许可协议发布，欢迎转载，演绎或用于商业目的，但是必须保留本文的署名 &lt;a href="http://hackerzhou.me/author/admin"&gt;hackerzhou&lt;/a&gt; 并包含 &lt;a href="http://hackerzhou.me/2012/05/vmware-hot-add-cpu-memory-feature-notes.html"&gt;原文链接&lt;/a&gt;。&lt;br /&gt;Copyright &amp;copy; 2026 &lt;a href="http://hackerzhou.me"&gt;hackerzhou&amp;#039;s blog&lt;/a&gt;  2009-2026&lt;/small&gt;&lt;/center&gt;&lt;/p&gt;		</description>
		<wfw:commentRss>http://hackerzhou.me/2012/05/vmware-hot-add-cpu-memory-feature-notes.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>果粉们忍够了！——App Store下载提速脚本</title>
		<link>http://hackerzhou.me/2012/04/accelerate-apps-store.html</link>
		<comments>http://hackerzhou.me/2012/04/accelerate-apps-store.html#comments</comments>
		<pubDate>Tue, 03 Apr 2012 13:41:20 +0000</pubDate>
		<dc:creator>hackerzhou</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[hosts]]></category>
		<category><![CDATA[iTunes]]></category>
		<category><![CDATA[提速]]></category>

		<guid isPermaLink="false">https://www.hackerzhou.me/?p=1283</guid>
		<description>
			&lt;p&gt;首先申明一点，我不是果粉，虽然我用各种苹果产品，但是我最喜欢的手机牌子依旧是火腿肠（HTC），最喜欢的笔记本牌子依旧是ThinkPad。写本文的主要目的是方便国内使用苹果设备的同学们，想必大家都碰到过在国内下载App Store龟速的情况。价格不菲的苹果产品在天朝几Mb的带宽下竟然在以数十KB的速度下载，是相当不能忍的事情。其实原因很简单，苹果在大陆没有服务器，外国人做的软件貌似都不太了解中国国情，在这个互联网自由基本靠翻墙的神奇国度里，iTunes不增加动态检测可用的以及最快的服务器的功能真是弱爆了。不知道CEO 库克的来访是不是预示着苹果公司对中国市场越来越重视，不过国外公司无法在境内建造数据中心，必须有落地的本土企业才行，估计苹果服务器要落地内地比较难。&lt;/p&gt;
&lt;p&gt;虽说iTunes自身不会那么智能的选择最快的接入点，但是我们可以帮它一把。网上之前也有过介绍类似PingInfoView之类批量Ping工具来找到相应最快的服务器的文章，大都hardcode了一些服务器IP，但哪些文章没有解决的就是如何得到哪些IP的，一旦苹果更改了服务器IP，那么一切都完了。所以，今天下午写了一个简单的Python脚本来动态的挑选最快的服务器。&lt;/p&gt;
&lt;p&gt;不多说，先上代码（以下是我写的部分，没有包含我调用的Python Ping的代码，完整版请见：&lt;br /&gt;
&lt;a href="https://github.com/hackerzhou/Scripts/blob/master/optimize_app_store_hosts.py" target="_blank"&gt;https://github.com/hackerzhou/Scripts/blob/master/optimize_app_store_hosts.py&lt;/a&gt;&lt;br /&gt;
完整版脚本可以直接用(sudo) python optimize_app_store_hosts.py调用，运行完成后会在当前目录下生成两个文件，apple_ip.txt包含了App Store不同的IP地址以及各自的ping响应时间，hosts文件包含了一个自动选取ping响应最快的那个IP生成的hosts列表，大家贴到C:\Windows\system32\drivers\etc\hosts（Windows），/etc/hosts（Mac）文件中就可以了，同时也可以传到越狱了的苹果设备中去。&lt;/p&gt;
&lt;p&gt;&lt;span style="color: #ff0000;"&gt;Note: Windows 用户执行命令python optimize_app_store_hosts.py，Mac用户执行sudo python optimize_app_store_hosts.py，因为Mac下只有root可以发出ICMP数据包。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;#!/usr/bin/env python&lt;br/&gt;import sys,socket&lt;br/&gt;&lt;br/&gt;PING_TIMEOUT = 1000&lt;br/&gt;def main():&lt;br/&gt;  hosts = &amp;#x5B;'a%d.phobos.apple.com' % i for i in range(1, 200)]&lt;br/&gt;  ips = get_ips(hosts)&lt;br/&gt;  records = ping_ips(ips)&lt;br/&gt;  output(records)&lt;br/&gt;&lt;br/&gt;def get_ips(hosts):&lt;br/&gt;  ips = &amp;#x5B;]&lt;br/&gt;  for host in hosts:&lt;br/&gt;    ips.extend(get_ip(host))&lt;br/&gt;  return {}.fromkeys(ips).keys()&lt;br/&gt;&lt;br/&gt;def get_ip(host):&lt;br/&gt;  print 'Getting IP for %s' % host&lt;br/&gt;  ip_records = socket.getaddrinfo(host, None, socket.AF_INET)&lt;br/&gt;  return &amp;#x5B;ip_record&amp;#x5B;4]&amp;#x5B;0] for ip_record in ip_records]&lt;br/&gt;&lt;br/&gt;def ping_ips(ips):&lt;br/&gt;  ping_result = &amp;#x5B;(ip, my_ping(ip)) for ip in ips]&lt;br/&gt;  ping_result.sort(cmp=lambda x, y: cmp(x&amp;#x5B;1], y&amp;#x5B;1]))&lt;br/&gt;  return ping_result&lt;br/&gt;&lt;br/&gt;def output(records):&lt;br/&gt;  record_lines = &amp;#x5B;'IP: %s\tTime: %f ms\n' % (record&amp;#x5B;0], round(record&amp;#x5B;1])) for record in records]&lt;br/&gt;  write_file('apple_ip.txt', record_lines)&lt;br/&gt;  if len(records) &amp;gt; 0 and records&amp;#x5B;0]&amp;#x5B;1] &amp;lt; PING_TIMEOUT:&lt;br/&gt;    ip = records&amp;#x5B;0]&amp;#x5B;0]&lt;br/&gt;    hosts_lines = &amp;#x5B;'%s\ta%d.phobos.apple.com\n' % (ip, i) for i in range(1, 2000)]&lt;br/&gt;    hosts_lines.insert(0, &amp;quot;#START APPLE STORE#\n&amp;quot;)&lt;br/&gt;    hosts_lines.append(&amp;quot;#END APPLE STORE#\n&amp;quot;)&lt;br/&gt;    write_file('hosts', hosts_lines)&lt;br/&gt;&lt;br/&gt;def write_file(filename, lines):&lt;br/&gt;  with open(filename, 'w') as output_file:&lt;br/&gt;    output_file.writelines(lines)&lt;br/&gt;  output_file.close()&lt;br/&gt;&lt;br/&gt;def my_ping(hostname):&lt;br/&gt;  return Ping(hostname, PING_TIMEOUT, 8).run(4)&lt;br/&gt;&lt;br/&gt;...&lt;br/&gt;(Visit https://github.com/hackerzhou/Scripts/blob/master/optimize_app_store_hosts.py to see the rest part)&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;代码很简单，因为App Store的hostname都长成类似a1.phobos.apple.com这样，然后我们就从1到199遍历下（其实网上说可能会到2000，我实验下来大量的IP是相同的，真正不同的IP也就只有几十个。保险起见还是遍历了199个，没有验证过，如果大家有相关资料可以回复更正我。）把遍历得到的IP列表去除重复的，然后再挨个ping，最后按照ping的平均响应时间来排序，选择最快的那一个，产生一个hosts文件。本来想直接写入系统hosts文件的，因为Mac下必须用sudo才能写hosts而且随便改别人hosts文件毕竟不太好，容易引起杀毒软件报警，所以就直接写入到一个本地文件中。&lt;br /&gt;
Python写起来还是相当方便和简练的，特别是使用推导式构建列表以及lambda语法，用惯了Java再换用Python就会有一种耳目一新的感觉～&lt;/p&gt;
&lt;br /&gt;&lt;p&gt;&lt;small&gt;&lt;i&gt;Post Tags: &lt;a href="http://hackerzhou.me/tag/app-store" rel="tag"&gt;App Store&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/hosts" rel="tag"&gt;hosts&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/itunes" rel="tag"&gt;iTunes&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/%e6%8f%90%e9%80%9f" rel="tag"&gt;提速&lt;/a&gt;&lt;/i&gt;&lt;/small&gt;&lt;hr /&gt;&lt;center&gt;&lt;small&gt;本文基于 &lt;a href="http://creativecommons.org/licenses/by/2.5/cn/"&gt;署名 2.5 中国大陆&lt;/a&gt; 许可协议发布，欢迎转载，演绎或用于商业目的，但是必须保留本文的署名 &lt;a href="http://hackerzhou.me/author/admin"&gt;hackerzhou&lt;/a&gt; 并包含 &lt;a href="http://hackerzhou.me/2012/04/accelerate-apps-store.html"&gt;原文链接&lt;/a&gt;。&lt;br /&gt;Copyright &amp;copy; 2026 &lt;a href="http://hackerzhou.me"&gt;hackerzhou&amp;#039;s blog&lt;/a&gt;  2009-2026&lt;/small&gt;&lt;/center&gt;&lt;/p&gt;		</description>
		<wfw:commentRss>http://hackerzhou.me/2012/04/accelerate-apps-store.html/feed</wfw:commentRss>
		<slash:comments>44</slash:comments>
		</item>
		<item>
		<title>忙里偷闲</title>
		<link>http://hackerzhou.me/2012/01/leisure-from-busy.html</link>
		<comments>http://hackerzhou.me/2012/01/leisure-from-busy.html#comments</comments>
		<pubDate>Tue, 31 Jan 2012 14:25:23 +0000</pubDate>
		<dc:creator>hackerzhou</dc:creator>
				<category><![CDATA[日记]]></category>
		<category><![CDATA[新年计划]]></category>

		<guid isPermaLink="false">https://www.hackerzhou.me/?p=1264</guid>
		<description>
			&lt;p&gt;不知不觉一个月没写博客了，年前由于进度紧张，工作压力比较大，年后则是因为娱乐活动太多了没顾上来。看到王怡同学@我的关于独立域名博客的文章才想起来是该写写了，不然都要长草了。买域名和vps其实当初也是犹豫过挺久的，毕竟是要花钱的。决定用vps主要是因为把自己写的东西放在自己站点上比较方便保险，后来发现配置、维护和调优服务器大大的提高了我对于linux的熟悉程度以及折腾各种各样程序的能力。关于域名，其实以前我的博客是hackerzhou.me，在万网注册的，万网的域名各种不好用，而且总会让人觉得这个域名不是你的。正好后来因为种种原因决定换域名，于是就在Go Daddy上注册了适合个人博客站点使用的.me域名，Go Daddy上有组合促销，其实也算不上很贵。&lt;/p&gt;
&lt;p&gt;长假期间吃吃喝喝，看电影看书，平均每天四部电影，打算把以前积攒下来的老片子都看掉再去学校下新电影。不知不觉已经存了4.5T的电影了，看过的也舍不得删，因为有些电影想一遍又一遍的看，比如肖申克的救赎，每看一次就会在一些袭击上有新的领悟。最近看的电影中给我感触最深的莫过于那些年了，跟我当年高中生活不谋而合，年少的时候需要有个“沈佳宜”来激励自己，当然，现在有我们家小姑娘来专职激励我了:P。同时最近也在看《浪潮之巅》这本书，读书方面我总是落后康哥和塔锭一大截，入手了kindle之后慢慢找回了儿时迷恋看书的感觉，好习惯要坚持下去的说。&lt;/p&gt;
&lt;p&gt;年前跟家人去菲律宾旅游，三天时间经历了从冬天到夏天再到冬天，不过凌晨的航班把人搞得累累的ToT。在菲律宾尝试泡了带有硫磺味的火山温泉，泡着温泉看着风景，那感觉的确比在黄山那个醉温泉好多了。在菲律宾可怜的单反总算不堪我折磨罢工了，快门数才过万啊，过几天送去修修，或许真的该换装备了。作为一个爱旅游的it青年，今年也有一些旅游计划，想跟宝贝一起去厦门转转，还想去婺源看美丽的乡村和古城。每次旅游的时候我都会有一些新想法和创意，似乎投身在大自然里能够挖掘自己的潜力。&lt;/p&gt;
&lt;p&gt;关于技术方面，最近想做一个软件license以及版本更新控制的小应用，想借鉴很多业界成熟的反盗版以及自动推送更新方法来小试牛刀下。自己喜欢写小软件的结果就是很多时候不能很好的对软件进行控制，最近就吃了这方面的亏，因此决定抽出时间来好好折腾下。同时，是时候把去年写的&lt;a href="http://love.hackerzhou.me" target="_blank"&gt;love.hackerzhou.me&lt;/a&gt;移植到Cloud Foundry上去了，目标是提供一个简单的可定制示爱网页服务，几次鼠标点击并输入几句话就可以产生出页面。&lt;/p&gt;
&lt;br /&gt;&lt;p&gt;&lt;small&gt;&lt;i&gt;Post Tags: &lt;a href="http://hackerzhou.me/tag/%e6%96%b0%e5%b9%b4%e8%ae%a1%e5%88%92" rel="tag"&gt;新年计划&lt;/a&gt;&lt;/i&gt;&lt;/small&gt;&lt;hr /&gt;&lt;center&gt;&lt;small&gt;本文基于 &lt;a href="http://creativecommons.org/licenses/by/2.5/cn/"&gt;署名 2.5 中国大陆&lt;/a&gt; 许可协议发布，欢迎转载，演绎或用于商业目的，但是必须保留本文的署名 &lt;a href="http://hackerzhou.me/author/admin"&gt;hackerzhou&lt;/a&gt; 并包含 &lt;a href="http://hackerzhou.me/2012/01/leisure-from-busy.html"&gt;原文链接&lt;/a&gt;。&lt;br /&gt;Copyright &amp;copy; 2026 &lt;a href="http://hackerzhou.me"&gt;hackerzhou&amp;#039;s blog&lt;/a&gt;  2009-2026&lt;/small&gt;&lt;/center&gt;&lt;/p&gt;		</description>
		<wfw:commentRss>http://hackerzhou.me/2012/01/leisure-from-busy.html/feed</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>盘点2011</title>
		<link>http://hackerzhou.me/2011/12/summary.html</link>
		<comments>http://hackerzhou.me/2011/12/summary.html#comments</comments>
		<pubDate>Thu, 29 Dec 2011 13:54:02 +0000</pubDate>
		<dc:creator>hackerzhou</dc:creator>
				<category><![CDATA[日记]]></category>
		<category><![CDATA[年终盘点]]></category>

		<guid isPermaLink="false">https://www.hackerzhou.me/?p=1247</guid>
		<description>
			&lt;p&gt;即将过去的2011年对我来说意义非凡，走出象牙塔融入社会，可以称之为人生milestone之一。毕业季的离愁别绪还时不时会在脑海中浮现，总想着什么时候同学们可以在聚在一起喝茶聊天。校园也是一座围城，课业繁重的时候总想着什么时候可以熬出头，而如今却怀念起读书时的无忧无虑。每周三四晚上陪宝贝一起上选修课，享受两三节课的相聚，浪漫温馨的相互调戏。&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;strong&gt;消费篇&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;步入职场后荷包宽裕了自然消费水平也整体跟上去了，请客也多了。不过好在除了少数数码产品和给宝贝的生日礼物外没有什么大件消费了，因此结余大大的有，我还是挺省吃俭用的～今年网购次数也开始多起来了，大概花了差不多1k在淘宝上，买的东西大体以数码产品的配件为主，还有少量的礼品，难怪同事戏称我为数码少年。。。今年升级了我房间的摆设，大大的桌子上同时摆下两台电脑，四个屏幕，各种数码产品也不愁没地方放了，被妈妈称为工作台，不过我感觉不错，体现专业感。&lt;/p&gt;
&lt;h4&gt;&lt;span style="text-decoration: underline;"&gt;&lt;strong&gt;技术篇&lt;/strong&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;出了学校不会再有考试的压力，学习的动力主要来自于自我的推动以及工作本身的需要。上个月初因为做的示爱网页而被认为是前端程序员，我乐此不疲的向别人解释我其实是写后端的。至于解释的原因，应该说是不想被真正的前端程序员笑话。自认为没什么技术难度的事情，要是被认为是出自专业选手之手，岂不是要贻笑大方？&lt;/p&gt;
&lt;p&gt;写了几个小程序，反响都不错，两个月前GPATools就有接近1w的使用量。不过都算是吃老本，没有太多技术上的新意和建树。不过算是开了个好头，让我初步明白怎么去设计一个受欢迎的工具，同时也让我意识到我对于市场动向这种东西还是有些直觉的。&lt;/p&gt;
&lt;p&gt;开发新产品的压力也迫使我去看相关的书，Python和Oracle也从原来的三角猫功夫提高了不少。Team里牛人辈出，想在众多牛人中立足，必须付出比别人更多的努力来汲取经验，取长补短。希望明年我在技术上能够有更大的进步，同时也希望我们的产品能大卖～&lt;/p&gt;
&lt;h4&gt;&lt;span style="text-decoration: underline;"&gt;&lt;strong&gt;娱乐&amp;amp;旅游篇&lt;/strong&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;本着娱乐工作两不误的精神，2011年我没少玩儿，跟宝贝一起去看电影去玩，跟朋友们一起K歌，也去了好几个地方旅游/出差，桂林，杭州，黄山，北京。每个地方都能带给我独特的感觉，触动到我心里不同的情怀。很期待以后能和宝贝一起出去旅游，让千山万水见证我们的爱。&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;&lt;span style="text-decoration: underline;"&gt;志愿者篇&lt;/span&gt;&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;今年是我第一次参与志愿者活动，JA学生公司的项目。回到高中看到那些稚嫩的小孩子很是感慨，想当年自己也曾经如此青葱过。明年我会参加更多的志愿者活动，或许我们势单力薄很难改变大环境，但是我们能在力所能及的范围内向弱势群体和那些需要我们帮助、关心的小孩子们播撒知识，播撒爱。希望明年能有更多的人们投入到志愿者活动中来。&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;strong&gt;感情篇&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;最后的也就是压轴的往往是最重要的，今年在感情上可谓一帆风顺，当然体贴懂事的宝贝有大大的功劳。虽然我们一个在五角场一个在张江，每周见面时间有限，但没什么能阻止我们彼此的想念，每天必须的电话粥和必备的“晚安，我爱你”。你说你会旺夫的，我觉得不假，连进EMC的笔试面试都如此顺利，你就是我的幸运小天使 ^_^～ 希望我能早点把宝贝娶回家～&lt;/p&gt;
&lt;br /&gt;&lt;p&gt;&lt;small&gt;&lt;i&gt;Post Tags: &lt;a href="http://hackerzhou.me/tag/%e5%b9%b4%e7%bb%88%e7%9b%98%e7%82%b9" rel="tag"&gt;年终盘点&lt;/a&gt;&lt;/i&gt;&lt;/small&gt;&lt;hr /&gt;&lt;center&gt;&lt;small&gt;本文基于 &lt;a href="http://creativecommons.org/licenses/by/2.5/cn/"&gt;署名 2.5 中国大陆&lt;/a&gt; 许可协议发布，欢迎转载，演绎或用于商业目的，但是必须保留本文的署名 &lt;a href="http://hackerzhou.me/author/admin"&gt;hackerzhou&lt;/a&gt; 并包含 &lt;a href="http://hackerzhou.me/2011/12/summary.html"&gt;原文链接&lt;/a&gt;。&lt;br /&gt;Copyright &amp;copy; 2026 &lt;a href="http://hackerzhou.me"&gt;hackerzhou&amp;#039;s blog&lt;/a&gt;  2009-2026&lt;/small&gt;&lt;/center&gt;&lt;/p&gt;		</description>
		<wfw:commentRss>http://hackerzhou.me/2011/12/summary.html/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>make学习笔记之优化makefile篇</title>
		<link>http://hackerzhou.me/2011/11/optimize-makefile.html</link>
		<comments>http://hackerzhou.me/2011/11/optimize-makefile.html#comments</comments>
		<pubDate>Wed, 23 Nov 2011 14:03:56 +0000</pubDate>
		<dc:creator>hackerzhou</dc:creator>
				<category><![CDATA[Linux/Mac OS X]]></category>
		<category><![CDATA[make]]></category>
		<category><![CDATA[Makefile]]></category>
		<category><![CDATA[调优]]></category>

		<guid isPermaLink="false">https://www.hackerzhou.me/?p=1227</guid>
		<description>
			&lt;p&gt;以前都只是用make，一直没好好研究makefile的写法。最近由于忍受不了每次3小时的编译过程，于是主动请缨对makefile进行了些优化来提高编译速度，试验了下效果很好，可以节省1-1.5小时。makefile可以简单的认为是make所识别的规则文件，描述了每个target之间的依赖关系以及编译方法，语法又和Shell Script类似，它也可以检查依赖关系，因此make被广泛的应用于编译源代码。写一些小项目的makefile都不会有太大的问题，而随着项目越来越大，其中的部件越来越多，编译过程越来越复杂。每个人都往里面加自己需要编译的东西，时间一长，理清楚各个makefile之间的调用以及依赖关系就变得越来越困难，因此每个小改动都得谨小慎微，改不好就是大灾难。很难想象一个脉络不清楚的体系能够有比较好的效率，本着不怕折腾的原则我这次就客串了下清道夫。由于是make的初学者，本文所述难免有所瑕疵，请各位多多包涵。&lt;/p&gt;
&lt;p&gt;makefile通过指定target之间的依赖关系构造了一颗编译树，树的叶子节点最先编译，而后一层层向上，直到根节点被编译。因此，这棵树的构造方法会显著的影响到编译的效率。下面我们来看一个例子，看看一个简单的优化，假设你有两个子项目B和C，编译B和C都比较耗时而且它们互相不依赖，但它们都有一个共同的依赖项目A。&lt;br /&gt;
目录结构如下所示：&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;|-A&lt;br/&gt;| |-makefile&lt;br/&gt;|-B&lt;br/&gt;| |-makefile&lt;br/&gt;|-C&lt;br/&gt;| |-makefile&lt;br/&gt;|-makefile&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;B的makefile内容大致如下，C和A也类似，sleep时间分别为1s和10s：&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;all:&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@echo &amp;quot;Target B sleep 5s&amp;quot;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sleep 5&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@echo &amp;quot;Target B complete&amp;quot;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;一个未经优化的./makefile内容可能是：&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;all: A&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cd B &amp;amp;&amp;amp; $(MAKE)&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cd C &amp;amp;&amp;amp; $(MAKE)&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@echo &amp;quot;Complete&amp;quot;&lt;br/&gt;&lt;br/&gt;A:&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cd A &amp;amp;&amp;amp; $(MAKE)&lt;br/&gt;&lt;br/&gt;.PHONY: A all&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;这样构造的makefile将会耗时(1+5+10)秒，make过程输出如下：&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;cd A &amp;amp;&amp;amp; make&lt;br/&gt;make&amp;#x5B;1]: Entering directory `/home/hackerzhou/test/A'&lt;br/&gt;Target A sleep 1s&lt;br/&gt;sleep 1&lt;br/&gt;Target B complete&lt;br/&gt;make&amp;#x5B;1]: Leaving directory `/home/hackerzhou/test/A'&lt;br/&gt;cd B &amp;amp;&amp;amp; make&lt;br/&gt;make&amp;#x5B;1]: Entering directory `/home/hackerzhou/test/B'&lt;br/&gt;Target B sleep 5s&lt;br/&gt;sleep 5&lt;br/&gt;Target B complete&lt;br/&gt;make&amp;#x5B;1]: Leaving directory `/home/hackerzhou/test/B'&lt;br/&gt;cd C &amp;amp;&amp;amp; make&lt;br/&gt;make&amp;#x5B;1]: Entering directory `/home/hackerzhou/test/C'&lt;br/&gt;Target C sleep 10s&lt;br/&gt;sleep 10&lt;br/&gt;Target C complete&lt;br/&gt;make&amp;#x5B;1]: Leaving directory `/home/hackerzhou/test/C'&lt;br/&gt;Complete&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;大家可以发现，此时make的执行是顺序的，就算使用make &amp;#8211;jobs=2也不能使用多job并行编译，究其原因是因为make的并行编译是依靠依赖关系来进行的，因此cd B &amp;amp;&amp;amp; $(MAKE)和cd C &amp;amp;&amp;amp; $(MAKE)两句不会被并行执行。于是我们就可以把该makefile改写成：&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;all: publish&lt;br/&gt;&lt;br/&gt;publish: B C&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@echo &amp;quot;Complete&amp;quot;&lt;br/&gt;&lt;br/&gt;C: A&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cd C &amp;amp;&amp;amp; $(MAKE)&lt;br/&gt;&lt;br/&gt;B: A&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cd B &amp;amp;&amp;amp; $(MAKE)&lt;br/&gt;&lt;br/&gt;A:&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cd A &amp;amp;&amp;amp; $(MAKE)&lt;br/&gt;&lt;br/&gt;.PHONY: A B C publish all&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;此时make编译的输出如下：&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;cd A &amp;amp;&amp;amp; make&lt;br/&gt;make&amp;#x5B;1]: Entering directory `/home/hackerzhou/test/A'&lt;br/&gt;Target A sleep 1s&lt;br/&gt;sleep 1&lt;br/&gt;Target B complete&lt;br/&gt;make&amp;#x5B;1]: Leaving directory `/home/hackerzhou/test/A'&lt;br/&gt;cd B &amp;amp;&amp;amp; make&lt;br/&gt;cd C &amp;amp;&amp;amp; make&lt;br/&gt;make&amp;#x5B;1]: Entering directory `/home/hackerzhou/test/C'&lt;br/&gt;make&amp;#x5B;1]: Entering directory `/home/hackerzhou/test/B'&lt;br/&gt;Target C sleep 10s&lt;br/&gt;sleep 10&lt;br/&gt;Target B sleep 5s&lt;br/&gt;sleep 5&lt;br/&gt;Target B complete&lt;br/&gt;make&amp;#x5B;1]: Leaving directory `/home/hackerzhou/test/B'&lt;br/&gt;Target C complete&lt;br/&gt;make&amp;#x5B;1]: Leaving directory `/home/hackerzhou/test/C'&lt;br/&gt;Complete&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;可以看出稍稍修改一下就可以使用&amp;#8211;jobs=2使得编译时间缩短到(10+1)s，B和C可以并行的完成，这只是我一个抛砖引玉的例子。&lt;/p&gt;
&lt;p&gt;诚然通过&amp;#8211;jobs来优化make编译也有其局限性：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;比如&amp;#8211;jobs的数量过大（超过cpu核的个数的时候性能就会直线下降）&lt;/li&gt;
&lt;li&gt;子makefile不一定能很好的支持&amp;#8211;jobs，可能也需要修改，会使得工程量变大&lt;/li&gt;
&lt;li&gt;如果编译过程中牵涉到大量的IO操作，并发的IO会成为瓶颈使得性能反而更慢&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;因此，优化make的方法应该因地制宜，分析出哪里是瓶颈才能对症下药。&lt;/p&gt;
&lt;br /&gt;&lt;p&gt;&lt;small&gt;&lt;i&gt;Post Tags: &lt;a href="http://hackerzhou.me/tag/make" rel="tag"&gt;make&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/makefile" rel="tag"&gt;Makefile&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/%e8%b0%83%e4%bc%98" rel="tag"&gt;调优&lt;/a&gt;&lt;/i&gt;&lt;/small&gt;&lt;hr /&gt;&lt;center&gt;&lt;small&gt;本文基于 &lt;a href="http://creativecommons.org/licenses/by/2.5/cn/"&gt;署名 2.5 中国大陆&lt;/a&gt; 许可协议发布，欢迎转载，演绎或用于商业目的，但是必须保留本文的署名 &lt;a href="http://hackerzhou.me/author/admin"&gt;hackerzhou&lt;/a&gt; 并包含 &lt;a href="http://hackerzhou.me/2011/11/optimize-makefile.html"&gt;原文链接&lt;/a&gt;。&lt;br /&gt;Copyright &amp;copy; 2026 &lt;a href="http://hackerzhou.me"&gt;hackerzhou&amp;#039;s blog&lt;/a&gt;  2009-2026&lt;/small&gt;&lt;/center&gt;&lt;/p&gt;		</description>
		<wfw:commentRss>http://hackerzhou.me/2011/11/optimize-makefile.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>程序员的浪漫-一周年主题网站</title>
		<link>http://hackerzhou.me/2011/11/programmers-romantic-1st-anniversary-website.html</link>
		<comments>http://hackerzhou.me/2011/11/programmers-romantic-1st-anniversary-website.html#comments</comments>
		<pubDate>Sat, 05 Nov 2011 14:29:39 +0000</pubDate>
		<dc:creator>hackerzhou</dc:creator>
				<category><![CDATA[HTML/CSS/JS]]></category>
		<category><![CDATA[随便写写]]></category>
		<category><![CDATA[FlowerPower]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[程序员的浪漫]]></category>

		<guid isPermaLink="false">https://www.hackerzhou.me/?p=1202</guid>
		<description>
			&lt;p&gt;2012/11/01 Update:&lt;br /&gt;
前阵子把页面包装成一个Sinatra的app放到了我们VMware的Cloud Foundry上，现在可以支持在线创建页面了。 http://iloveu.cloudfoundry.com &lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;这几天我做的一周年主题网站 &lt;a href="http://love.hackerzhou.me" target="_blank"&gt;http://love.hackerzhou.me&lt;/a&gt; ，在人人网和微博上引起了很广泛的反响，大大超出我的预料。我原来预计大概有几千人看就很不得了了，现在在人人网上有2,600+的直接转发量、微博上也有350+的直接/间接转发量，有接近200,000的点击量，甚至还吸引了媒体(&lt;a href="http://news.xhby.net/system/2011/11/05/012009569.shtml"&gt;扬子晚报&lt;/a&gt; &amp;amp; &lt;a href="http://xwcb.eastday.com/c/20111107/u1a936079.html"&gt;新闻晨报&lt;/a&gt;)的朋友们。诚惶诚恐的同时也很高兴能改变大家对于程序员先入为主的印象，有很多朋友在留言/评论中直接表示改变了对程序员呆板木讷的印象。一般提起程序员，很多人的第一印象是来去匆匆、不善与人交际也不懂浪漫，因此张江男一度成为大龄剩男的代名词。而事实上，程序员有着惊人的创造力和活力，特别是在帮mm解决各种各样的问题上，比如eBay和Cisco就是因为创始人要帮老婆解决问题而创建的。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.hackerzhou.me/wp-content/uploads/2011/11/2011-11-02-20-00-00.png"&gt;&lt;img decoding="async" class="aligncenter" title="2011-11-02 20-00-00" src="https://www.hackerzhou.me/wp-content/uploads/2011/11/2011-11-02-20-00-00.png" alt="" width="70%" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;其实很早就在想在一周年的时候给mm一个惊喜，有过很多主意比如手绘卡片，但是很不幸，小时候的素描和水粉画功底基本全还老师了，尝试了一下还是作罢；也想过摆爱心烛阵，拍DV搞后期制作，荧光油漆画爱心甚至楼下唱情歌，但身为程序员就要有程序员的范儿不是么，搞得跟文艺青年一样很容易画虎不成反类犬变成一线之隔的2B青年的。时间上也并不充裕，只能在业余时间制作，并且作为一个secret project得避开mm的视线，诸多限制使得做决定越来越困难。&lt;/p&gt;
&lt;p&gt;就在日子一天天过去，离着deadline越来越近的时候，同门师兄&lt;a href="http://techblog.iamzellux.com/"&gt;zellux&lt;/a&gt;为tt姐做了&lt;a href="http://lovett.cc" target="_blank"&gt;lovett.cc&lt;/a&gt;的周年纪念网站，顿时给了我一个思路。zellux师兄用了box2d类库来模仿物理重力环境，碰撞及弹跳真是绚丽的没的说。随后开始确定整个作品的scope和detail design，在公司里学到的一整套流程派上用场了，跟工程师们学技术，跟产品经理学市场定位和策略。想法有很多，为了按期交付所以按照优先级砍掉了一些当时看起来并不十分重要的功能设计，这些想法我也会一点点付诸于实践，毕竟1.0版更多的是为了传达一个理念和信号。最终选择了&lt;a href="http://www.openrise.com/lab/FlowerPower/"&gt;FlowerPower&lt;/a&gt;这个以前就很喜欢的HTML5特效demo，记得第一次看到flowerpower的时候，我就想把它鼠标绘图的方式改成自动绘图，但那时没有想好绘制是么图形。一开始想用花朵来书写mm的名字，试验了一下效果不理想，因此使用了一个mm比较喜欢的下端尖尖的爱心图形，使用一个调整过参数的爱心函数绘制而成。后来觉得flowerpower默认的黑色背景太压抑，因而换成了浅色背景，同时也修改花朵的RGB以及alpha值来使得色调更加协调。&lt;/p&gt;
&lt;p&gt;上述工作被很多人认为是最绚丽的部分，其实我更耗时间的步骤是构思并写表白的代码及注释，前后删删改改十几次，还要因为布局因素调整用词和语句结构。由于我们的缘分始于Java，因此采用Java来编写这段代码，而配色则用我跟我mm最常用的IDE——Eclipse的默认色系。代码以及注释采用打字机方式输出，仿真打代码的效果，其实本来还想加上敲击键盘的音效的，最后因为找不到时间符合的音效而作罢。技术上的实现再简单不过了，就是一个一个字符append上去，注意HTML Tag和HTML Entities的处理。最后就是微调的过程了，一些UI布局和浏览器兼容性在这时候被提上日程，包括那个检测HTML5 Canvas兼容性的警告输出也是在那时候做的。很多朋友为了浏览这个页面安装了Chrome/Firefox/IE9等新版的浏览器，看来我还在潜移默化之中推进了市场上浏览器的升级换代。&lt;/p&gt;
&lt;p&gt;以上就是我设计这个网页的过程，我总结下来，真正重要的是一颗有爱的心和创新的精神，技术上的实现永远不是最大的问题。我整理了下代码，在GitHub上创建了一个项目&lt;a href="https://github.com/hackerzhou/Love" target="_blank"&gt;https://github.com/hackerzhou/Love&lt;/a&gt;，方便有兴趣继续开发的朋友们继续开发，同时我会尝试在我们VMware的&lt;a href="http://www.cloudfoundry.com" target="_blank"&gt;CloudFoundry&lt;/a&gt;上面建立一个对应的App来帮助更多需要这种页面的人们，做好以后大家可以通过wizard来定制自己的示爱页面。总之，祝天下有情人终成眷属，心中有爱自然能打造自己独特的浪漫来让另一半感动。&lt;/p&gt;
&lt;br /&gt;&lt;p&gt;&lt;small&gt;&lt;i&gt;Post Tags: &lt;a href="http://hackerzhou.me/tag/flowerpower" rel="tag"&gt;FlowerPower&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/html5" rel="tag"&gt;HTML5&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/jquery" rel="tag"&gt;jQuery&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/%e7%a8%8b%e5%ba%8f%e5%91%98%e7%9a%84%e6%b5%aa%e6%bc%ab" rel="tag"&gt;程序员的浪漫&lt;/a&gt;&lt;/i&gt;&lt;/small&gt;&lt;hr /&gt;&lt;center&gt;&lt;small&gt;本文基于 &lt;a href="http://creativecommons.org/licenses/by/2.5/cn/"&gt;署名 2.5 中国大陆&lt;/a&gt; 许可协议发布，欢迎转载，演绎或用于商业目的，但是必须保留本文的署名 &lt;a href="http://hackerzhou.me/author/admin"&gt;hackerzhou&lt;/a&gt; 并包含 &lt;a href="http://hackerzhou.me/2011/11/programmers-romantic-1st-anniversary-website.html"&gt;原文链接&lt;/a&gt;。&lt;br /&gt;Copyright &amp;copy; 2026 &lt;a href="http://hackerzhou.me"&gt;hackerzhou&amp;#039;s blog&lt;/a&gt;  2009-2026&lt;/small&gt;&lt;/center&gt;&lt;/p&gt;		</description>
		<wfw:commentRss>http://hackerzhou.me/2011/11/programmers-romantic-1st-anniversary-website.html/feed</wfw:commentRss>
		<slash:comments>153</slash:comments>
		</item>
		<item>
		<title>杂</title>
		<link>http://hackerzhou.me/2011/10/essay.html</link>
		<comments>http://hackerzhou.me/2011/10/essay.html#comments</comments>
		<pubDate>Fri, 14 Oct 2011 13:02:56 +0000</pubDate>
		<dc:creator>hackerzhou</dc:creator>
				<category><![CDATA[日记]]></category>
		<category><![CDATA[加班]]></category>
		<category><![CDATA[学习]]></category>

		<guid isPermaLink="false">https://www.hackerzhou.me/?p=1192</guid>
		<description>
			&lt;p&gt;不知不觉都工作三个月了，最近因刘斐敏同学的《校友风采》约稿要求，要求码点字。原本我以为code写多了文章就写不来了，但是当在回家的公共汽车上用手机开vi断断续续写了1024个字后，我知道还没有退化的那么严重。以下是答复的稿件，姑且贴上来。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;今年刚毕业没工作多少时间就被约稿，诚惶诚恐，本文权当分享一下个人经历，还请各位学长学姐多多指教。&lt;/p&gt;
&lt;p&gt;弹指间四年已经过去了，四年前坐在计算中心机房里写Hello World的大一新生到如今踏入职场，期间经历了很多让我开心过和感动过的事情，认识了很多可以交心的好朋友，这些朋友也在潜移默化地影响着我。寝室里刘康是我们班公认的神一般的存在，再难的OS lab也只要一通宵就能搞定，每次我睡了一觉了睁开眼还是能看到康哥的台灯亮着。单从他奇迹般的减掉40斤体重的经历就可以看出其惊人的毅力，他一直是我努力学习的榜样。&lt;/p&gt;
&lt;p&gt;从一开始的只会写Hello World到如今对语言的触类旁通，在软院的学习教会了我很多，不仅仅是书本上的知识，更重要的是学习的能力。我一直认为学无止境，学校学到的最重要的东西应该是如何更好的去学习而不是仅仅为了得到一个好分数，所谓授人以渔。一直都说软院的学生动手实践能力比较强，我对此深有感触，经过那么多lab和project历练下来的都是coding和debug的能手。相比于计算机系的同学，我们在计算理论方面可能有所欠缺，但是实践能力在我看来是更胜一筹的，可能这也是SE和CE的不同培养方向的一种具体表现。&lt;/p&gt;
&lt;p&gt;踏入职场，最初有些不太适应。开始朝九晚六的生活，开始要写weekly report，开始对自己own的部分负责，开始慢慢习惯用英语和老外开会讨论，开始习惯早睡早起。在工作岗位上肯定会有书到用时方恨少的感触，学习能力的强弱直接决定了工作的效率和成果。比如还没工作多少时间，就因为工作的需要，边查资料边看书的学了Linux shell编程，现在因为同样的原因正在试着用python。在学校的时候很多情况下都是self-driven的，很多隐形作业做不做纯粹靠自觉，但在公司就有很多原因驱动你去学习。每天学习新知识未必能立刻感觉到不同，一日不见如隔三秋未免有些夸张，不过我相信只要持之以恒，一定会感觉到能力的提升。&lt;/p&gt;
&lt;p&gt;最近参加了几次同学聚会，大家都说工作累、加班多，在社交网络上也经常能看到同学的诉苦抱怨。其实我个人是比较抵触加班文化的，加班文化往往代表着劳动力的极度不被尊重。我能够理解偶尔的、必要的加班，八月的时候为了赶VMworld用的demo也曾经加班到九点。但是常态的加班甚至是加班文化要么凸现了要么项目没有计划好要么就是这个公司崇尚的价值观有问题。我觉得要有自己思考和学习的时间才会有长进，而常态的加班无疑会使静下心来思考成为泡影。记得曾经在公司的career talk上听到过有同事这么提问说十年的工作经验会不会变成是一年经验的十次重复。这是一个值得我们每个人思考的好问题，只有不断的充实自己，才能让自己的经验更加有价值而不是简单的重复。我想大部分的加班工作都不会有太多的创新，纯粹是为了完成任务而加班，因此很有可能变成重复的经验。同时，加班不仅不可的避免伤害自己的健康，而且使得和家人的交流愈发的减少，长远来看得不偿失。&lt;/p&gt;
&lt;p&gt;好了，胡言乱语了那么多，大家看得开心就好～祝学长学姐们事业有成～&lt;/p&gt;
&lt;br /&gt;&lt;p&gt;&lt;small&gt;&lt;i&gt;Post Tags: &lt;a href="http://hackerzhou.me/tag/%e5%8a%a0%e7%8f%ad" rel="tag"&gt;加班&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/%e5%ad%a6%e4%b9%a0" rel="tag"&gt;学习&lt;/a&gt;&lt;/i&gt;&lt;/small&gt;&lt;hr /&gt;&lt;center&gt;&lt;small&gt;本文基于 &lt;a href="http://creativecommons.org/licenses/by/2.5/cn/"&gt;署名 2.5 中国大陆&lt;/a&gt; 许可协议发布，欢迎转载，演绎或用于商业目的，但是必须保留本文的署名 &lt;a href="http://hackerzhou.me/author/admin"&gt;hackerzhou&lt;/a&gt; 并包含 &lt;a href="http://hackerzhou.me/2011/10/essay.html"&gt;原文链接&lt;/a&gt;。&lt;br /&gt;Copyright &amp;copy; 2026 &lt;a href="http://hackerzhou.me"&gt;hackerzhou&amp;#039;s blog&lt;/a&gt;  2009-2026&lt;/small&gt;&lt;/center&gt;&lt;/p&gt;		</description>
		<wfw:commentRss>http://hackerzhou.me/2011/10/essay.html/feed</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>虚拟磁盘工具vmware-mount及其引发的安全担忧</title>
		<link>http://hackerzhou.me/2011/09/a-useful-tool-vmware-mount-and-its-security-issue.html</link>
		<comments>http://hackerzhou.me/2011/09/a-useful-tool-vmware-mount-and-its-security-issue.html#comments</comments>
		<pubDate>Thu, 29 Sep 2011 14:49:02 +0000</pubDate>
		<dc:creator>hackerzhou</dc:creator>
				<category><![CDATA[应用]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[VDDK]]></category>
		<category><![CDATA[VMDK]]></category>
		<category><![CDATA[vmware-mount]]></category>
		<category><![CDATA[虚拟化]]></category>

		<guid isPermaLink="false">https://www.hackerzhou.me/?p=1180</guid>
		<description>
			&lt;p&gt;最近在做一些提高团队开发/测试效率的工具，了解到了一些vmware有意思的小工具，本文介绍的就是vmware-mount。vmware-mount是&lt;a href="http://www.vmware.com/support/developer/vddk/"&gt;VMware Virtual Disk Development Kit&lt;/a&gt;里的一个工具，VMware workstation和vSphere都采用vmdk文件来表示磁盘，而vmware-mount可以用来把远程或本地的vmdk mount成为一个本地磁盘或者挂载到某个挂载点。&lt;/p&gt;
&lt;p&gt;vmware-mount的安装及运行（仅示范VDDK Linux版的挂载remote vmdk功能，更多详细用法请参考官方文档）：&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;#Install VDDK&lt;br/&gt;./vmware-vix-disklib-distrib/vmware-install.pl&lt;br/&gt;#Use ESX host directly&lt;br/&gt;vmware-mount -h &amp;lt;ESX_HOST_IP&amp;gt; -u &amp;lt;ESX_USERNAME&amp;gt; -F &amp;lt;FILE_CONTAINS_ESX_PASSWORD&amp;gt; &amp;quot;&amp;lt;VMDK PATH IN DATASTORE&amp;gt;&amp;quot; &amp;lt;MOUNT_POINT&amp;gt;&lt;br/&gt;#or you can use VC&lt;br/&gt;vmware-mount -v &amp;quot;&amp;lt;InventoryPath_of_VM&amp;gt;&amp;quot; -h &amp;lt;VC_IP&amp;gt; -u &amp;lt;VC_USERNAME&amp;gt; -F &amp;lt;FILE_CONTAINS_VC_PASSWORD&amp;gt; &amp;quot;&amp;lt;VMDK PATH IN DATASTORE&amp;gt;&amp;quot; &amp;lt;MOUNT_POINT&amp;gt;&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;从以上命令可以看出：一旦我们得到了VC或者是ESX的权限，我们就可以直接读写虚拟机的磁盘（如果磁盘未加密），这样就很容易造成信息的泄漏。虽然ESX用户有着控制整个服务器的权限，但我觉得这种权限应该仅局限于创建/删除虚拟机，而没有权限不经过该虚拟机用户的授权就可以读取甚至修改虚拟机里的文件应该是不被许可的。简单的来说就是：就算管理员可以删除我的虚拟机，也不能未经授权就读取我的文件。&lt;/p&gt;
&lt;p&gt;由于目前大多数主流的Linux系统都不使用明文来保存系统密码了，但是依旧可以采用替换/etc/shadow文件的方式来用已知的密码来替换未知的密码。在/etc/shadow文件中记录的用户密码信息有着特定的格式，诸如“hackerzhou:[一堆密文及加密方法]:15240:0:99999:7:::”。所以，执行如下命令可以把root密码设置为12345。&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;sed -i 's#^\(root:\)&amp;#x5B;^:]*#\1$6$sHSPz6Pw$xIP/V.HKQdhfaagzoUxSkbjOYFET8pQDE754ZBDWAmu8LM4LYvBXdRqAOAi.x1isBd5.xZUw9S.rpHWAREVC/1#' &amp;quot;${MOUNT_POINT}/etc/shadow&amp;quot;&lt;br/&gt;#MOUNT_POINT is the mounting point of VMDK&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;以上就是我对于vmware-mount工具可能造成的安全问题的一些思考，希望大家在实施的时候要注意保护ESX 和VC的用户名/密码，并对用户权限加以限制，毕竟一旦用户使用vSphere Client登录了VC/ESX，可以通过手工添加磁盘的方法来把别的虚拟机的VMDK mount到本机上。&lt;/p&gt;
&lt;br /&gt;&lt;p&gt;&lt;small&gt;&lt;i&gt;Post Tags: &lt;a href="http://hackerzhou.me/tag/security" rel="tag"&gt;security&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/vddk" rel="tag"&gt;VDDK&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/vmdk" rel="tag"&gt;VMDK&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/vmware-mount" rel="tag"&gt;vmware-mount&lt;/a&gt;, &lt;a href="http://hackerzhou.me/tag/%e8%99%9a%e6%8b%9f%e5%8c%96" rel="tag"&gt;虚拟化&lt;/a&gt;&lt;/i&gt;&lt;/small&gt;&lt;hr /&gt;&lt;center&gt;&lt;small&gt;本文基于 &lt;a href="http://creativecommons.org/licenses/by/2.5/cn/"&gt;署名 2.5 中国大陆&lt;/a&gt; 许可协议发布，欢迎转载，演绎或用于商业目的，但是必须保留本文的署名 &lt;a href="http://hackerzhou.me/author/admin"&gt;hackerzhou&lt;/a&gt; 并包含 &lt;a href="http://hackerzhou.me/2011/09/a-useful-tool-vmware-mount-and-its-security-issue.html"&gt;原文链接&lt;/a&gt;。&lt;br /&gt;Copyright &amp;copy; 2026 &lt;a href="http://hackerzhou.me"&gt;hackerzhou&amp;#039;s blog&lt;/a&gt;  2009-2026&lt;/small&gt;&lt;/center&gt;&lt;/p&gt;		</description>
		<wfw:commentRss>http://hackerzhou.me/2011/09/a-useful-tool-vmware-mount-and-its-security-issue.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
