<?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>GuoJing&#039;s Blog &#124; 献给未来的回忆 &#187; 软件开发</title>
	<atom:link href="http://www.jguoer.com/blog/index.php/archives/category/software-development/feed" rel="self" type="application/rss+xml" />
	<link>http://www.jguoer.com/blog</link>
	<description>献给未来的回忆</description>
	<lastBuildDate>Thu, 02 Feb 2012 16:00:40 +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>简单才有意义</title>
		<link>http://www.jguoer.com/blog/index.php/archives/2098</link>
		<comments>http://www.jguoer.com/blog/index.php/archives/2098#comments</comments>
		<pubDate>Wed, 30 Nov 2011 05:41:42 +0000</pubDate>
		<dc:creator>诡异的西红柿</dc:creator>
				<category><![CDATA[软件开发]]></category>

		<guid isPermaLink="false">http://www.jguoer.com/blog/?p=2098</guid>
		<description><![CDATA[这两天常常和guolin同学讨论程序员的一些事情，其实说的不多，也没什么特别总结的。早上做了一点东西反倒有点灵光一现的感觉，所以记录下来。既然简单，那么也说的简单点。

嗨，说白了，设计如果太复杂，那么问题也多，以后也会有很多问题。特别是大一点的web应用，一般来说都是算法算数据，前端展现，有时候需要隐藏某些数据的时候，都采用前端去做一下筛选的方法。想想看，这种做法即不简单、也不直白，而且也没解决问题。随着逻辑的增长，反而束手束脚，带来很多问题。最简单的方法就是在算法的表里把数据去掉就行了，而前端只要读出数据就成。

不过话说回来，虽然说的简单，做起来却难，先不说公司那么多人、上级下级的问题。即便是自己，如果没有一定的洁癖，估计也会想着“姑且就这么快点实现需求吧”这样的事情吧。所以问题就总是一拖再拖，最后再来个彻底的重构，可是怎么想也不是划算和值得提倡的东西。

所以，遇到了这样的问题，还不如从自己开始，马上开始动手，否则复杂的东西就没有意义了。]]></description>
			<content:encoded><![CDATA[<p>这两天常常和guolin同学讨论程序员的一些事情，其实说的不多，也没什么特别总结的。早上做了一点东西反倒有点灵光一现的感觉，所以记录下来。</p>
<p>嗨，说白了，设计如果太复杂，那么问题也多，以后也会有很多问题。特别是大一点的web应用，一般来说都是算法算数据，前端展现，有时候需要隐藏某些数据的时候，都采用前端去做一下筛选的方法。想想看，这种做法即不简单、也不直白，而且也没解决问题。随着逻辑的增长，反而束手束脚，带来很多问题。最简单的方法就是在算法的表里把数据去掉就行了，而前端只要读出数据就成。</p>
<p>不过话说回来，虽然说的简单，做起来却难，先不说公司那么多人、上级下级的问题。即便是自己，如果没有一定的洁癖，估计也会想着“姑且就这么快点实现需求吧”这样的事情吧。所以问题就总是一拖再拖，最后再来个彻底的重构，可是怎么想也不是划算和值得提倡的东西。</p>
<p>所以，遇到了这样的问题，还不如从自己开始，马上开始动手，否则复杂的东西就没有意义了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jguoer.com/blog/index.php/archives/2098/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>memcached的分布式的一点笔记</title>
		<link>http://www.jguoer.com/blog/index.php/archives/2035</link>
		<comments>http://www.jguoer.com/blog/index.php/archives/2035#comments</comments>
		<pubDate>Wed, 16 Nov 2011 13:21:03 +0000</pubDate>
		<dc:creator>诡异的西红柿</dc:creator>
				<category><![CDATA[软件开发]]></category>

		<guid isPermaLink="false">http://www.jguoer.com/blog/?p=2035</guid>
		<description><![CDATA[最近看了mixi的memcached的分布式的一些入门文章，虽然有些知识算是比较老的知识了，但是还是做一下笔记，虽然拖了好久都没有写（以致于我tab打开都不敢关，怕没感觉了），今天终于下定决心写了。。以后可以信手拈来拿来看，也算做一个备份整理。

我大概看了几篇相关的文章，一起整理了。

豆瓣条目在<a href="http://book.douban.com/subject/4722865/">这里</a>，翻译在<a href="http://tech.idv2.com/2008/07/24/memcached-004/">这里</a>，原文在<a href="http://gihyo.jp/dev/feature/01/memcached/0004">这里</a>。

简单的记录一下。memcached的server一般不做事，即便是分布式，memcached的server端也很简单，主要是客户端来做这个逻辑处理。也就是说，当获取一个key，value对的时候，根据key来做一个hash，然后根据hash存储在服务器上面。这个过程很简单，但是存储的方法有很多。

首先介绍根据余数计算分散。大概逻辑如下。

还有一些链接：

<a href="http://weblogs.java.net/blog/tomwhite/archive/2007/11/consistent_hash.html">Consistent Hashing</a>

<a href="http://alpha.mixi.co.jp/blog/?p=158">スマートな分散で快適キャッシュライフ</a>]]></description>
			<content:encoded><![CDATA[<p>最近看了mixi的memcached的分布式的一些入门文章，虽然有些知识算是比较老的知识了，但是还是做一下笔记，虽然拖了好久都没有写（以致于我tab打开都不敢关，怕没感觉了），今天终于下定决心写了。。以后可以信手拈来拿来看，也算做一个备份整理。</p>
<p>我大概看了几篇相关的文章，一起整理了。</p>
<p>豆瓣条目在<a href="http://book.douban.com/subject/4722865/">这里</a>，翻译在<a href="http://tech.idv2.com/2008/07/24/memcached-004/">这里</a>，原文在<a href="http://gihyo.jp/dev/feature/01/memcached/0004">这里</a>。</p>
<p>简单的记录一下。memcached的server一般不做事，即便是分布式，memcached的server端也很简单，主要是客户端来做这个逻辑处理。也就是说，当获取一个key，value对的时候，根据key来做一个hash，然后根据hash存储在服务器上面。这个过程很简单，但是存储的方法有很多。</p>
<p>首先介绍根据余数计算分散。大概逻辑如下。</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-2038" title="基本结构" src="http://www.jguoer.com/blog/wp-content/uploads/2011/11/TH400_0004-01.png" alt="" width="400" height="318" /></p>
<p>上图是一个基本结构，日语不用管。最下面的是应用程序，中间的黄色一大坨的是hash算法，最上面的是node1，node2等服务器。</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-2037" title="set" src="http://www.jguoer.com/blog/wp-content/uploads/2011/11/TH400_0004-02.png" alt="" width="400" height="345" /></p>
<p>上图是set操作，set的时候，根据算法（余数计算分散）得到某个key的存储的节点的值，假设是node1，那么就存到node1上了。</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-2036" title="get" src="http://www.jguoer.com/blog/wp-content/uploads/2011/11/TH400_0004-03.png" alt="" width="400" height="346" /></p>
<p>上图是get操作，get的时候，根据同样的算法，同样得到这个key的存储的节点的值，得到的是node1，那么就从node1得到数据。</p>
<p>这个地方都很简单，也很容易理解。通过将不同的键保存到不同的服务器上的方式实现了memcached的分布式。memcached服务器增多后，键就会分散，即使一台memcached服务器发生故障 无法连接，也不会影响其他的缓存，系统依然能继续运行。</p>
<p>不过这样也有显而易见的缺点，当添加和移除服务器的时候，会产生很多的miss，因为余数会产生变化。当添加和移除的服务器越多的时候，miss就越多，也会给数据库服务器带来很大的负担。原文中指出当添加一个节点，大概命中率会降低到23%，比较恐怖。</p>
<p>所以有了Consistent Hashing。</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-2041" title="Consistent Hashing" src="http://www.jguoer.com/blog/wp-content/uploads/2011/11/TH400_0004-04.png" alt="" width="400" height="274" /></p>
<p><strong>和前面的一样，先求服务器节点的hash值（server node的哈希值），然后分部在0～2^32的圆上。然后用同样的方法求出节点的hash值，然后顺时针查找到最近的节点上，存储在此服务器上。</strong></p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-2040" title="Consistent Hashing 添加服务器" src="http://www.jguoer.com/blog/wp-content/uploads/2011/11/TH400_0004-05.png" alt="" width="400" height="305" /></p>
<p>添加服务器的时候，只会影响到这个服务器逆时针到前一个节点中的所有的key，其他的均不会受到影响。Consistent Hashing抑制了键的重新分布。 另外，也有Consistent Hashing的实现方法采用了虚拟节点的思想，为每个物理节点在圆上分配100～200个点，从而减小服务器增减时的缓存重新分布。</p>
<p>使不使用Consistent Hashing的方法对命中率有很大的影响，下面是摘抄的一些数据。</p>
<p>一开始服务器4台，5000个记录。追加一台的结果。</p>
<p>1)</p>
<ul>
<li>合计服务器数 4</li>
<li>追加 1</li>
<li>命中率 77%</li>
</ul>
<p>2)</p>
<ul>
<li>合计服务器数 6</li>
<li>追加 2</li>
<li>命中率 64%</li>
</ul>
<p>3)</p>
<ul>
<li>合计服务器数 7</li>
<li>追加 3</li>
<li>命中率 58%</li>
</ul>
<p>从上面来看好处还是显而易见的，另外一个数据显示，不使用Consistent Hashing的话，服务器从4台增加到5台的时候，命中率只有19%。</p>
<p>另外，mixi推荐4G服务器，memcached用3G，再大就会有内存交换，就会更慢。</p>
<p>还有一些链接：</p>
<p><a href="http://weblogs.java.net/blog/tomwhite/archive/2007/11/consistent_hash.html">Consistent Hashing</a></p>
<p><a href="http://alpha.mixi.co.jp/blog/?p=158">スマートな分散で快適キャッシュライフ</a></p>
<p>其中第一篇可以摘抄的有：</p>
<p>You can see the effect of this in the following plot which I produced by simulating storing 10,000 objects in 10 caches using the code described below. On the x-axis is the number of replicas of cache points (with a logarithmic scale). When it is small, we see that the distribution of objects across caches is unbalanced, since the standard deviation as a percentage of the mean number of objects per cache (on the y-axis, also logarithmic) is high. As the number of replicas increases the distribution of objects becomes more balanced. This experiment shows that a figure of one or two hundred replicas achieves an acceptable balance (a standard deviation that is roughly between 5% and 10% of the mean).</p>
<p style="text-align: center;"><img src="http://www.jguoer.com/blog/wp-content/uploads/2011/11/ch-graph.png" alt="" title="test" width="400" height="400" class="alignnone size-full wp-image-2043" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jguoer.com/blog/index.php/archives/2035/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>移动设备(Python)添加Google Analytics的一些经验</title>
		<link>http://www.jguoer.com/blog/index.php/archives/1381</link>
		<comments>http://www.jguoer.com/blog/index.php/archives/1381#comments</comments>
		<pubDate>Mon, 24 Jan 2011 08:57:14 +0000</pubDate>
		<dc:creator>诡异的西红柿</dc:creator>
				<category><![CDATA[软件开发]]></category>

		<guid isPermaLink="false">http://www.jguoer.com/blog/?p=1381</guid>
		<description><![CDATA[最近一直在做移动设备的Google Analytics(后面称GA)，遇到了很多问题，尝试了很多办法，最后勉强做出了一个基本可用的东西，虽然成果不怎样，但是还是记录一下这个过程中遇到的问题吧，方便以后查看，如果有遇到相同问题的朋友又解决了的话，希望能够给我一些意见。

<a href="http://code.google.com/mobile/analytics/docs/web/" target="_blank">Google官方移动版部署的可以看这里。</a>

一开始，一切显得那么美好，访问了Google官方的移动版页面之后，发现貌似很容易，因为Google官方网站上都有了Sample Code，下下来看一下，测试一下，只要有了数据就说明ok了，虽然没有python版本，但是自己捣腾一下改写成一个python版本的也不是大问题，弄完了之后放到网站上，嗯，发现要等很长时间才能获得数据，ok，等，等了第二天之后，发现果然有数据了，虽然数据数为1，但是说明数据还是传达到了。

但是，等等，连续过了5天，发现还是1，说明数据有问题啊，仔细检查了代码和参数，发现没有什么问题。与此同时，运维的同学来找我了，说是这PV不对啊，翻翻了(因为官网是在服务器端发送请求的)，所以要改，所以就tail日志发送到GA。不知道GA是否会去访问手机浏览器的cookie，如果访问的话，凑参数可能还不能完全凑正确，不过看了几个参数，都是可以凑的，否则还不能手动的去向GA发送数据。

其实，最主要的问题还是数据为1这个，这个问题真头疼，问了新闻组也没人回复，调整参数还要8个到12个小时才有结果，非常郁闷，后来我搜了一下国外的新闻组，发现，有很多人遇到了跟我一样的问题，而且Google没有回复，后来好不容易搜到了一个解决方法，这个方法非常的magic，虽然不好理解，但是还是奏效了，<a href="http://www.google.com/support/forum/p/Google%20Analytics/thread?tid=1d2ce688a2e0b0df&#38;hl=en" target="_blank">例子可以看这里</a>。

最后发现，核心的问题就在于Google给的Sample里面url是这样的。

<div class="code">
http://www.google-analytics.com/__utm.gif?utmwv=4.4sp&#038;utmn=1265992655&#038;utmhn=www.mysite.gov&#038;utmr=-&#038;utmp=%2FBLSW%2Fpdfs%2FAge_Of_Majority.pdf&#038;utmac=UA-10916562-4&#038;utmcc=<span style="color:red"><b>__utma%3D999.999.999.999.999.1%3B</b></span>&#038;utmvid=0x72137fa74c3d8c6e&#038;utmip=68.54.126.0
</div>

其中，utma应该不是999.999这样一致的数字，一开始我也怀疑了，但是没有证据，毕竟源代码也是这样写的，于是我估计GA可能会在接受参数的时候进行编码等操作，但是我测试过，好像并不是这样，或者参数有什么固定的顺序？真是太不好调试了，所以测了几天都没有效果。然后看了上面的那篇文章，据说是把_utm.gif里面的逻辑逆向了，于是就有了如此magic的代码。

<div class="code">
<div><span style="color: #0000FF;">def</span><span style="color: #000000;"> gen_utma():&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;domain_name </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">'</span><span style="color: #800000;">www.jguoer.com</span><span style="color: #800000;">'</span><span style="color: #000000;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;  <br />
&#160;&#160;&#160;&#160;domain_hash </span><span style="color: #000000;">=</span><span style="color: #000000;"> 0&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;g </span><span style="color: #000000;">=</span><span style="color: #000000;"> 0&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;  <br />
&#160;&#160;&#160;&#160;i </span><span style="color: #000000;">=</span><span style="color: #000000;"> len(domain_name) </span><span style="color: #000000;">-</span><span style="color: #000000;"> </span><span style="color: #000000;">1</span><span style="color: #000000;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;  <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;  <br />
&#160;&#160;&#160;&#160;</span><span style="color: #0000FF;">while</span><span style="color: #000000;"> i</span><span style="color: #000000;">&#62;=</span><span style="color: #000000;">0:&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;c </span><span style="color: #000000;">=</span><span style="color: #000000;"> ord(domain_name[i])&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;domain_hash </span><span style="color: #000000;">=</span><span style="color: #000000;"> ((domain_hash </span><span style="color: #000000;">&#60;&#60;</span><span style="color: #000000;"> </span><span style="color: #000000;">6</span><span style="color: #000000;">) </span><span style="color: #000000;">&#38;</span><span style="color: #000000;"> </span><span style="color: #000000;">0xfffffff</span><span style="color: #000000;">) </span><span style="color: #000000;">+</span><span style="color: #000000;"> c </span><span style="color: #000000;">+</span><span style="color: #000000;"> (c </span><span style="color: #000000;">&#60;&#60;</span><span style="color: #000000;"> </span><span style="color: #000000;">14</span><span style="color: #000000;">)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;  <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;g </span><span style="color: #000000;">=</span><span style="color: #000000;"> domain_hash </span><span style="color: #000000;">&#38;</span><span style="color: #000000;"> </span><span style="color: #000000;">0xfe00000</span><span style="color: #000000;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span style="color: #0000FF;">if</span><span style="color: #000000;"> g</span><span style="color: #000000;">!=</span><span style="color: #000000;">0:&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;  <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;domain_hash </span><span style="color: #000000;">=</span><span style="color: #000000;"> domain_hash </span><span style="color: #000000;">^</span><span style="color: #000000;"> (g </span><span style="color: #000000;">&#62;&#62;</span><span style="color: #000000;"> </span><span style="color: #000000;">21</span><span style="color: #000000;">)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;i </span><span style="color: #000000;">=</span><span style="color: #000000;"> i </span><span style="color: #000000;">-</span><span style="color: #000000;"> </span><span style="color: #000000;">1</span><span style="color: #000000;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;rnd_num </span><span style="color: #000000;">=</span><span style="color: #000000;"> str(randint(</span><span style="color: #000000;">1147483647</span><span style="color: #000000;">, </span><span style="color: #000000;">2147483647</span><span style="color: #000000;">))&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;  <br />
&#160;&#160;&#160;&#160;time_num </span><span style="color: #000000;">=</span><span style="color: #000000;"> str(time.time()).split(</span><span style="color: #800000;">'</span><span style="color: #800000;">.</span><span style="color: #800000;">'</span><span style="color: #000000;">)[0]&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />
&#160;&#160;&#160;&#160;_utma </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">'</span><span style="color: #800000;">%s.%s.%s.%s.%s.%s</span><span style="color: #800000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">%</span><span style="color: #000000;"> (domain_hash, rnd_num, time_num,&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;  <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;time_num, time_num, </span><span style="color: #000000;">1</span><span style="color: #000000;">)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;  <br />
&#160;&#160;&#160;&#160;</span><span style="color: #0000FF;">return</span><span style="color: #000000;"> _utma  <br />
</span></div>
</div>

上面的代码太magic，但是是很必要的，就是为了替换奇怪的999.999那串字符的，如果不这么做的话，估计连最基本的访问量的数字都没有。不过，从另一点来看这个代码，但是这里只是将域名给hash了，并没有任何其他的参数，所以也没有什么其他的信息，至于Google文档里面的utmvid和utmip参数可有可无，不知道如何修改。

好在最后，最最基本的功能还是达到了。其他的参数还在研究中，我将代码发布到了github上面，并且一解决问题我就会更新源代码。<a href="https://github.com/GuoJing/Google-Analytics-Mobile-Python" target="_blank">源代码可以看这里。</a>

如果，你真的遇到过我这样的问题并且解决了的话，希望能提点提点我。]]></description>
			<content:encoded><![CDATA[<p>最近一直在做移动设备的Google Analytics(后面称GA)，遇到了很多问题，尝试了很多办法，最后勉强做出了一个基本可用的东西，虽然成果不怎样，但是还是记录一下这个过程中遇到的问题吧，方便以后查看，如果有遇到相同问题的朋友又解决了的话，希望能够给我一些意见。</p>
<p><a href="http://code.google.com/mobile/analytics/docs/web/" target="_blank">Google官方移动版部署的可以看这里。</a></p>
<p>一开始，一切显得那么美好，访问了Google官方的移动版页面之后，发现貌似很容易，因为Google官方网站上都有了Sample Code，下下来看一下，测试一下，只要有了数据就说明ok了，虽然没有python版本，但是自己捣腾一下改写成一个python版本的也不是大问题，弄完了之后放到网站上，嗯，发现要等很长时间才能获得数据，ok，等，等了第二天之后，发现果然有数据了，虽然数据数为1，但是说明数据还是传达到了。</p>
<p>但是，等等，连续过了5天，发现还是1，说明数据有问题啊，仔细检查了代码和参数，发现没有什么问题。与此同时，运维的同学来找我了，说是这PV不对啊，翻翻了(因为官网是在服务器端发送请求的)，所以要改，所以就tail日志发送到GA。不知道GA是否会去访问手机浏览器的cookie，如果访问的话，凑参数可能还不能完全凑正确，不过看了几个参数，都是可以凑的，否则还不能手动的去向GA发送数据。</p>
<p>其实，最主要的问题还是数据为1这个，这个问题真头疼，问了新闻组也没人回复，调整参数还要8个到12个小时才有结果，非常郁闷，后来我搜了一下国外的新闻组，发现，有很多人遇到了跟我一样的问题，而且Google没有回复，后来好不容易搜到了一个解决方法，这个方法非常的magic，虽然不好理解，但是还是奏效了，<a href="http://www.google.com/support/forum/p/Google%20Analytics/thread?tid=1d2ce688a2e0b0df&amp;hl=en" target="_blank">例子可以看这里</a>。</p>
<p>最后发现，核心的问题就在于Google给的Sample里面url是这样的。</p>
<div class="code">
http://www.google-analytics.com/__utm.gif?utmwv=4.4sp&#038;utmn=1265992655&#038;utmhn=www.mysite.gov&#038;utmr=-&#038;utmp=%2FBLSW%2Fpdfs%2FAge_Of_Majority.pdf&#038;utmac=UA-10916562-4&#038;utmcc=<span style="color:red"><b>__utma%3D999.999.999.999.999.1%3B</b></span>&#038;utmvid=0x72137fa74c3d8c6e&#038;utmip=68.54.126.0
</div>
<p>其中，utma应该不是999.999这样一致的数字，一开始我也怀疑了，但是没有证据，毕竟源代码也是这样写的，于是我估计GA可能会在接受参数的时候进行编码等操作，但是我测试过，好像并不是这样，或者参数有什么固定的顺序？真是太不好调试了，所以测了几天都没有效果。然后看了上面的那篇文章，据说是把_utm.gif里面的逻辑逆向了，于是就有了如此magic的代码。</p>
<div class="code">
<div><span style="color: #0000FF;">def</span><span style="color: #000000;"> gen_utma():&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;domain_name </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">&#8216;</span><span style="color: #800000;">www.jguoer.com</span><span style="color: #800000;">&#8216;</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />
&nbsp;&nbsp;&nbsp;&nbsp;domain_hash </span><span style="color: #000000;">=</span><span style="color: #000000;"> 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;g </span><span style="color: #000000;">=</span><span style="color: #000000;"> 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />
&nbsp;&nbsp;&nbsp;&nbsp;i </span><span style="color: #000000;">=</span><span style="color: #000000;"> len(domain_name) </span><span style="color: #000000;">-</span><span style="color: #000000;"> </span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF;">while</span><span style="color: #000000;"> i</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">0:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c </span><span style="color: #000000;">=</span><span style="color: #000000;"> ord(domain_name[i])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;domain_hash </span><span style="color: #000000;">=</span><span style="color: #000000;"> ((domain_hash </span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;"> </span><span style="color: #000000;">6</span><span style="color: #000000;">) </span><span style="color: #000000;">&amp;</span><span style="color: #000000;"> </span><span style="color: #000000;">0xfffffff</span><span style="color: #000000;">) </span><span style="color: #000000;">+</span><span style="color: #000000;"> c </span><span style="color: #000000;">+</span><span style="color: #000000;"> (c </span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;"> </span><span style="color: #000000;">14</span><span style="color: #000000;">)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g </span><span style="color: #000000;">=</span><span style="color: #000000;"> domain_hash </span><span style="color: #000000;">&amp;</span><span style="color: #000000;"> </span><span style="color: #000000;">0xfe00000</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF;">if</span><span style="color: #000000;"> g</span><span style="color: #000000;">!=</span><span style="color: #000000;">0:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;domain_hash </span><span style="color: #000000;">=</span><span style="color: #000000;"> domain_hash </span><span style="color: #000000;">^</span><span style="color: #000000;"> (g </span><span style="color: #000000;">&gt;&gt;</span><span style="color: #000000;"> </span><span style="color: #000000;">21</span><span style="color: #000000;">)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i </span><span style="color: #000000;">=</span><span style="color: #000000;"> i </span><span style="color: #000000;">-</span><span style="color: #000000;"> </span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;rnd_num </span><span style="color: #000000;">=</span><span style="color: #000000;"> str(randint(</span><span style="color: #000000;">1147483647</span><span style="color: #000000;">, </span><span style="color: #000000;">2147483647</span><span style="color: #000000;">))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />
&nbsp;&nbsp;&nbsp;&nbsp;time_num </span><span style="color: #000000;">=</span><span style="color: #000000;"> str(time.time()).split(</span><span style="color: #800000;">&#8216;</span><span style="color: #800000;">.</span><span style="color: #800000;">&#8216;</span><span style="color: #000000;">)[0]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;_utma </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">&#8216;</span><span style="color: #800000;">%s.%s.%s.%s.%s.%s</span><span style="color: #800000;">&#8216;</span><span style="color: #000000;"> </span><span style="color: #000000;">%</span><span style="color: #000000;"> (domain_hash, rnd_num, time_num,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time_num, time_num, </span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF;">return</span><span style="color: #000000;"> _utma  <br />
</span></div>
</div>
<p>上面的代码太magic，但是是很必要的，就是为了替换奇怪的999.999那串字符的，如果不这么做的话，估计连最基本的访问量的数字都没有。不过，从另一点来看这个代码，但是这里只是将域名给hash了，并没有任何其他的参数，所以也没有什么其他的信息，至于Google文档里面的utmvid和utmip参数可有可无，不知道如何修改。</p>
<p>好在最后，最最基本的功能还是达到了。其他的参数还在研究中，我将代码发布到了github上面，并且一解决问题我就会更新源代码。<a href="https://github.com/GuoJing/Google-Analytics-Mobile-Python" target="_blank">源代码可以看这里。</a></p>
<p>如果，你真的遇到过我这样的问题并且解决了的话，希望能提点提点我。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jguoer.com/blog/index.php/archives/1381/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>差异</title>
		<link>http://www.jguoer.com/blog/index.php/archives/1274</link>
		<comments>http://www.jguoer.com/blog/index.php/archives/1274#comments</comments>
		<pubDate>Wed, 01 Sep 2010 10:16:28 +0000</pubDate>
		<dc:creator>诡异的西红柿</dc:creator>
				<category><![CDATA[软件开发]]></category>

		<guid isPermaLink="false">http://www.jguoer.com/blog/?p=1274</guid>
		<description><![CDATA[做开源的东西已经一段时间了，从微软阵营转到开源的几个月是非常痛苦的。

曾经一直认为学好了一门语言之后，其他的语言学起来都是相通的，但是现在觉得这句话还是有失偏颇的，因为一门语言背后的是一个社区的风格习惯，这样的风格习惯会导致项目开发产生不同的编码，生产风格，最后导致项目中出现一些问题。

其实，了解这些差异也是很重要的。

当然，选择的路不同，到最后的习惯和方向也会很不同，这也就是前面说的那句话有失偏颇的问题。如果.Net接触多了，你写web service会考虑使用WCF之流，自然也会做出“相应”的社区中认为较好的应用或框架，但是拿到另一个社区可能完完全全就是垃圾，因为信奉的“宗教”不同，自然就会有问题。

当然，世界上还是有一些公理的，如如何写一个好的软件，设计模式等。]]></description>
			<content:encoded><![CDATA[<p>做开源的东西已经一段时间了，从微软阵营转到开源的几个月是非常痛苦的。</p>
<p>曾经一直认为学好了一门语言之后，其他的语言学起来都是相通的，但是现在觉得这句话还是有失偏颇的，因为一门语言背后的是一个社区的风格习惯，这样的风格习惯会导致项目开发产生不同的编码，生产风格，最后导致项目中出现一些问题。</p>
<p>其实，了解这些差异也是很重要的。</p>
<p>当然，选择的路不同，到最后的习惯和方向也会很不同，这也就是前面说的那句话有失偏颇的问题。如果.Net接触多了，你写web service会考虑使用WCF之流，自然也会做出“相应”的社区中认为较好的应用或框架，但是拿到另一个社区可能完完全全就是垃圾，因为信奉的“宗教”不同，自然就会有问题。</p>
<p>当然，世界上还是有一些公理的，如如何写一个好的软件，设计模式等。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jguoer.com/blog/index.php/archives/1274/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mac OS/Linux下automake的用法</title>
		<link>http://www.jguoer.com/blog/index.php/archives/1198</link>
		<comments>http://www.jguoer.com/blog/index.php/archives/1198#comments</comments>
		<pubDate>Wed, 30 Jun 2010 10:25:04 +0000</pubDate>
		<dc:creator>诡异的西红柿</dc:creator>
				<category><![CDATA[软件开发]]></category>

		<guid isPermaLink="false">http://www.jguoer.com/blog/?p=1198</guid>
		<description><![CDATA[经常需要写一些小工具，这些工具有时候简单的就用python，性能高一点的就需要c，而我又喜欢用命令行和vi写程序，所以写makefile自然就成了麻烦中的麻烦了，不过好在可以使用automake，不过网上并没有很详细的说automake如何使用（都是东说一块西说一块的），查了一下然后整理了一下，发上来，就当自己做笔记，也方便了后面的人，高手自然自动飘过即可。

首先我们假设在这个目录下已经有一些代码了，例如main.c，我们使用automake来创建makefile，步骤如下。

1）首先在目录下运行autoscan。
2）修改configure.scan为configure.in。
3）编辑configure.in
<div class="code">
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
# 这下面都是需要填写的内容，如包的名称，版本号和bug报告的邮箱
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_CONFIG_SRCDIR([main.c])
AC_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT
</div>
我们可以看到上面的默认配置，我们修改一下配置，修改后就成了下面这个样子。
<div class="code">
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.61)
# 添加我们的配置，如包的名称为helloworld，版本0.1，邮箱等
<b>AC_INIT(helloworld, 0.1, soundbbg@gmail.com)</b>
AC_CONFIG_SRCDIR([main.c])
AC_CONFIG_HEADER([config.h])
# 添加一些基本配置
<b>AM_INIT_AUTOMAKE(main, 1.0)</b>
# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.
# 在这里添加输出makefile
<b>AC_OUTPUT([makefile])</b>
</div>
4）修改完成后退出，运行aclocal。
5）运行完成后运行autoheader

6）完成之后，我们创建一个makefile.am，并修改如下。

<div class="code">
AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=main
main_SOURCES=main.c
</div>

7）修改完成后运行automake --add-missing
8）运行完成后运行./configure

OK我们的makefile就生成好了，这个时候只要我们make一下就可以编译程序了。编译完成后可以运行./xxxx 来运行自己的程序。]]></description>
			<content:encoded><![CDATA[<p>经常需要写一些小工具，这些工具有时候简单的就用python，性能高一点的就需要c，而我又喜欢用命令行和vi写程序，所以写makefile自然就成了麻烦中的麻烦了，不过好在可以使用automake，不过网上并没有很详细的说automake如何使用（都是东说一块西说一块的），查了一下然后整理了一下，发上来，就当自己做笔记，也方便了后面的人，高手自然自动飘过即可。</p>
<p>首先我们假设在这个目录下已经有一些代码了，例如main.c，我们使用automake来创建makefile，步骤如下。</p>
<p>1）首先在目录下运行autoscan。<br />
2）修改configure.scan为configure.in。<br />
3）编辑configure.in</p>
<div class="code">
#                                               -*- Autoconf -*-<br />
# Process this file with autoconf to produce a configure script.<br />
AC_PREREQ(2.61)<br />
# 这下面都是需要填写的内容，如包的名称，版本号和bug报告的邮箱<br />
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)<br />
AC_CONFIG_SRCDIR([main.c])<br />
AC_CONFIG_HEADER([config.h])<br />
# Checks for programs.<br />
AC_PROG_CC<br />
# Checks for libraries.<br />
# Checks for header files.<br />
# Checks for typedefs, structures, and compiler characteristics.<br />
# Checks for library functions.<br />
AC_OUTPUT
</div>
<p>我们可以看到上面的默认配置，我们修改一下配置，修改后就成了下面这个样子。</p>
<div class="code">
#                                               -*- Autoconf -*-<br />
# Process this file with autoconf to produce a configure script.</p>
<p>AC_PREREQ(2.61)<br />
# 添加我们的配置，如包的名称为helloworld，版本0.1，邮箱等<br />
<b>AC_INIT(helloworld, 0.1, soundbbg@gmail.com)</b><br />
AC_CONFIG_SRCDIR([main.c])<br />
AC_CONFIG_HEADER([config.h])<br />
# 添加一些基本配置<br />
<b>AM_INIT_AUTOMAKE(main, 1.0)</b><br />
# Checks for programs.<br />
AC_PROG_CC</p>
<p># Checks for libraries.</p>
<p># Checks for header files.</p>
<p># Checks for typedefs, structures, and compiler characteristics.</p>
<p># Checks for library functions.<br />
# 在这里添加输出makefile<br />
<b>AC_OUTPUT([makefile])</b>
</div>
<p>4）修改完成后退出，运行aclocal。<br />
5）运行完成后运行autoheader</p>
<p>6）完成之后，我们创建一个makefile.am，并修改如下。</p>
<div class="code">
AUTOMAKE_OPTIONS=foreign<br />
bin_PROGRAMS=main<br />
main_SOURCES=main.c
</div>
<p>7）修改完成后运行automake &#8211;add-missing<br />
8）运行完成后运行./configure</p>
<p>OK我们的makefile就生成好了，这个时候只要我们make一下就可以编译程序了。编译完成后可以运行./xxxx 来运行自己的程序。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jguoer.com/blog/index.php/archives/1198/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Google App Engine上使用Mako</title>
		<link>http://www.jguoer.com/blog/index.php/archives/1130</link>
		<comments>http://www.jguoer.com/blog/index.php/archives/1130#comments</comments>
		<pubDate>Fri, 18 Jun 2010 15:36:53 +0000</pubDate>
		<dc:creator>诡异的西红柿</dc:creator>
				<category><![CDATA[软件开发]]></category>

		<guid isPermaLink="false">http://www.jguoer.com/blog/?p=1130</guid>
		<description><![CDATA[由于使用了Google App Engine，而且也经常使用Mako，觉得Mako的语法其实挺不错的，而且也比较容易理解，性能也不错，所以就想在Google App Engine上使用Mako，尝试了一下，并不是很难，具体做法如下。

1.下载mako http://www.makotemplates.org/downloads/Mako-0.2.5.tar.gz，可以使用wget url命令获取，Mac下需要下载一个wget，我习惯用wget了。
2.解压缩。
3.安装应该在/资源库/Python/2.5（或你使用的版本）/site-packages/Makoxxxxxx/mako。
4.拷贝上面的资源到你的应用程序目录下。

当然，还要写一点代码去使用mako，如果你不愿意去实现，可以看看我怎么做，Go on。

在<a href="http://www.jguoer.com/blog/index.php/archives/1122" target="_blank">上一篇</a>文章中，我写了一个项目模板，就是一个基本上完整的，可以扩展和维护的项目的结构，这里，我更改了一些项目的模板，这个项目的模板的设计可以很方便的使用Mako模板实现，这个结构我就不多说了，<a href="http://www.jguoer.com/blog/index.php/archives/1122" target="_blank">具体在这里可以看到</a>。

这个模板里我加了一个lib/template.py，用于包装Mako一些方法，代码可以自己下了看。在public里面，包装了一些静态文件的路径的变量，以便以后可以只需要更改一个地方，方便维护，并将Django模板的html变成Mako模板。

使用方法：

引用

from lib.template import st

使用

self.response.out.write(st("main.mako", **locals()))

其中main.mako已经设定为在template之下

下载

<a href="http://www.jguoer.com/blog/wp-content/uploads/2010/06/makosample.zip">makosample</a>]]></description>
			<content:encoded><![CDATA[<p>由于使用了Google App Engine，而且也经常使用Mako，觉得Mako的语法其实挺不错的，而且也比较容易理解，性能也不错，所以就想在Google App Engine上使用Mako，尝试了一下，并不是很难，具体做法如下。</p>
<p>1.下载mako http://www.makotemplates.org/downloads/Mako-0.2.5.tar.gz，可以使用wget url命令获取，Mac下需要下载一个wget，我习惯用wget了。<br />
2.解压缩。<br />
3.安装应该在/资源库/Python/2.5（或你使用的版本）/site-packages/Makoxxxxxx/mako。<br />
4.拷贝上面的资源到你的应用程序目录下。</p>
<p>当然，还要写一点代码去使用mako，如果你不愿意去实现，可以看看我怎么做，Go on。</p>
<p>在<a href="http://www.jguoer.com/blog/index.php/archives/1122" target="_blank">上一篇</a>文章中，我写了一个项目模板，就是一个基本上完整的，可以扩展和维护的项目的结构，这里，我更改了一些项目的模板，这个项目的模板的设计可以很方便的使用Mako模板实现，这个结构我就不多说了，<a href="http://www.jguoer.com/blog/index.php/archives/1122" target="_blank">具体在这里可以看到</a>。</p>
<p>这个模板里我加了一个lib/template.py，用于包装Mako一些方法，代码可以自己下了看。在public里面，包装了一些静态文件的路径的变量，以便以后可以只需要更改一个地方，方便维护，并将Django模板的html变成Mako模板。</p>
<p>使用方法：</p>
<p>引用</p>
<p>from lib.template import st</p>
<p>使用</p>
<p>self.response.out.write(st(&#8220;main.mako&#8221;, **locals()))</p>
<p>其中main.mako已经设定为在template之下</p>
<p>下载</p>
<p><a href="http://www.jguoer.com/blog/wp-content/uploads/2010/06/makosample.zip">makosample</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jguoer.com/blog/index.php/archives/1130/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mac OS X玩Python+Google App Engine</title>
		<link>http://www.jguoer.com/blog/index.php/archives/1122</link>
		<comments>http://www.jguoer.com/blog/index.php/archives/1122#comments</comments>
		<pubDate>Fri, 18 Jun 2010 13:44:08 +0000</pubDate>
		<dc:creator>诡异的西红柿</dc:creator>
				<category><![CDATA[软件开发]]></category>

		<guid isPermaLink="false">http://www.jguoer.com/blog/?p=1122</guid>
		<description><![CDATA[今天有点时间，于是想找一个支持Python的服务器，后来很失望，因为国内几乎没有Python的服务器，好吧，只能说我自己的期望有点高，但是又不想自己弄一个机器当服务器还配置很多东西，于是就选择了<a href="http://code.google.com/intl/zh-CN/appengine/" target="_blank">Google App Engine</a>。
<p style="text-align: center;"><img class="size-full wp-image-1123 aligncenter" title="gae1" src="http://www.jguoer.com/blog/wp-content/uploads/2010/06/gae1.png" alt="" width="500" height="246" /></p>
Google App Engine可以当作是一个托管的开发平台，有一套自己的环境，我们只需要下载SDK安装并且使用相应的工具开发，然后部署即可，非常简单，因为我喜欢Python，于是就使用Python作为开发环境。

首先注册一个App Engine帐户，如果有Google帐户的话，那么就很容易，直接创建一个应用。创建很简单，就如下图即可，创建之后就有控制板等告诉你谁访问过之类的，这里我就不废话了。
<p style="text-align: center;"><img class="size-full wp-image-1125 aligncenter" title="gae2" src="http://www.jguoer.com/blog/wp-content/uploads/2010/06/gae2.png" alt="" width="500" height="400" /></p>
例如这里我创建了一个名字叫jguoer的应用，这是个标志，后面我们需要，创建完成之后我们可以去这个页面<a href="http://code.google.com/intl/zh-CN/appengine/downloads.html" target="_blank">下载SDK和工具</a>，当然，我是Mac OS，你可以下载属于你的平台的SDK，很小，很轻量。

下面就是Mac OS X里的内容了，下载完成之后，打开安装的程序，如下图。
<p style="text-align: center;"><img class="size-full wp-image-1126   aligncenter" style="border: none; background: transparent;" title="gae3" src="http://www.jguoer.com/blog/wp-content/uploads/2010/06/gae3.png" alt="" width="629" height="457" /></p>
我们可以单击“+”添加一个应用，这个应用的名字必须和我们前面创建的应用的名字相同，创建很简单，输入名字就行，创建完成后，我们可以点上面的Run运行我们的程序（通过127.0.0.1:port端口号访问），也可以点Deploy部署到网站上去，然后通过前面设置的域名访问。

我们创建一个应用程序后，我们可以在相应的位置找到文件，默认情况下只有3个文件，分别是两个yaml配置文件，然后一个是main.py文件，返回的是一个“Hello World”，直接运行就能够看到这个Hello World。当然，这样并不好，我们还需要有很多其他的文件，并创建一个更好的结构，更加可读，可扩展，可维护，这样就最好了，于是我自己改了一些结构，可以参考着使用。

可以在这里下载：

<a href="http://www.jguoer.com/blog/wp-content/uploads/2010/06/sample.zip">sample</a>

其中的目录实际上被我改成了routing.py，controller，template，lib，stylesheets等目录，其中routing是专门设置Url规范的，controller和template分别放py和html模板，lib放公用的库文件，stylesheets等自然是放样式表等静态文件了。当然，如果要放js等文件的话，可以修改app.yaml文件。现在默认是处理了stylesheets静态目录。

实际上使用Google App Engine跑一个应用程序是很简单的事情，例如<a href="http://jguoer.appspot.com/" target="_blank">http://jguoer.appspot.com/</a>，就是一个只用5分钟就完成的网站。

<a href="http://code.google.com/intl/zh-CN/appengine/docs/python/gettingstarted/" target="_blank">更多，请参考这里。</a>]]></description>
			<content:encoded><![CDATA[<p>今天有点时间，于是想找一个支持Python的服务器，后来很失望，因为国内几乎没有Python的服务器，好吧，只能说我自己的期望有点高，但是又不想自己弄一个机器当服务器还配置很多东西，于是就选择了<a href="http://code.google.com/intl/zh-CN/appengine/" target="_blank">Google App Engine</a>。</p>
<p style="text-align: center;"><img class="size-full wp-image-1123 aligncenter" title="gae1" src="http://www.jguoer.com/blog/wp-content/uploads/2010/06/gae1.png" alt="" width="500" height="246" /></p>
<p>Google App Engine可以当作是一个托管的开发平台，有一套自己的环境，我们只需要下载SDK安装并且使用相应的工具开发，然后部署即可，非常简单，因为我喜欢Python，于是就使用Python作为开发环境。</p>
<p>首先注册一个App Engine帐户，如果有Google帐户的话，那么就很容易，直接创建一个应用。创建很简单，就如下图即可，创建之后就有控制板等告诉你谁访问过之类的，这里我就不废话了。</p>
<p style="text-align: center;"><img class="size-full wp-image-1125 aligncenter" title="gae2" src="http://www.jguoer.com/blog/wp-content/uploads/2010/06/gae2.png" alt="" width="500" height="400" /></p>
<p>例如这里我创建了一个名字叫jguoer的应用，这是个标志，后面我们需要，创建完成之后我们可以去这个页面<a href="http://code.google.com/intl/zh-CN/appengine/downloads.html" target="_blank">下载SDK和工具</a>，当然，我是Mac OS，你可以下载属于你的平台的SDK，很小，很轻量。</p>
<p>下面就是Mac OS X里的内容了，下载完成之后，打开安装的程序，如下图。</p>
<p style="text-align: center;"><img class="size-full wp-image-1126   aligncenter" style="border: none; background: transparent;" title="gae3" src="http://www.jguoer.com/blog/wp-content/uploads/2010/06/gae3.png" alt="" width="629" height="457" /></p>
<p>我们可以单击“+”添加一个应用，这个应用的名字必须和我们前面创建的应用的名字相同，创建很简单，输入名字就行，创建完成后，我们可以点上面的Run运行我们的程序（通过127.0.0.1:port端口号访问），也可以点Deploy部署到网站上去，然后通过前面设置的域名访问。</p>
<p>我们创建一个应用程序后，我们可以在相应的位置找到文件，默认情况下只有3个文件，分别是两个yaml配置文件，然后一个是main.py文件，返回的是一个“Hello World”，直接运行就能够看到这个Hello World。当然，这样并不好，我们还需要有很多其他的文件，并创建一个更好的结构，更加可读，可扩展，可维护，这样就最好了，于是我自己改了一些结构，可以参考着使用。</p>
<p>可以在这里下载：</p>
<p><a href="http://www.jguoer.com/blog/wp-content/uploads/2010/06/sample.zip">sample</a></p>
<p>其中的目录实际上被我改成了routing.py，controller，template，lib，stylesheets等目录，其中routing是专门设置Url规范的，controller和template分别放py和html模板，lib放公用的库文件，stylesheets等自然是放样式表等静态文件了。当然，如果要放js等文件的话，可以修改app.yaml文件。现在默认是处理了stylesheets静态目录。</p>
<p>实际上使用Google App Engine跑一个应用程序是很简单的事情，例如<a href="http://jguoer.appspot.com/" target="_blank">http://jguoer.appspot.com/</a>，就是一个只用5分钟就完成的网站。</p>
<p><a href="http://code.google.com/intl/zh-CN/appengine/docs/python/gettingstarted/" target="_blank">更多，请参考这里。</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jguoer.com/blog/index.php/archives/1122/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>关于程序员坚守的思考</title>
		<link>http://www.jguoer.com/blog/index.php/archives/1083</link>
		<comments>http://www.jguoer.com/blog/index.php/archives/1083#comments</comments>
		<pubDate>Mon, 24 May 2010 13:48:28 +0000</pubDate>
		<dc:creator>诡异的西红柿</dc:creator>
				<category><![CDATA[软件开发]]></category>

		<guid isPermaLink="false">http://www.jguoer.com/blog/?p=1083</guid>
		<description><![CDATA[已经工作了很长时间，一直也没有说一下这个“<strong>关于程序员坚守的思考</strong>”的问题，这个问题不是针对现在的公司，只是我这么长时间来工作的一些心得，特别是关于做为一个程序员一些心得。

在产品开发过程中，肯定是会有不同的人承担不同的职责并在团队中做自己相应的任务，每个人的目的都不同，比如产品的目的是要尽快的发布产品，而程序员的目的是要写出高质量的代码等等。实际上，写出高质量的代码并不是一件很难的事情，随着经验的增长和阅历的丰富，高质量的代码并不是一个难以攀爬的高峰，但是为什么产品会出现越来越慢或者越来越差的局面呢，我觉得这是有几个因素造成的。

首先是程序员的能力，虽然我们这个地方主要不会探讨程序员的能力。因为我们首先将程序员当成是有责任心，能力可佳的人，至少这样的人不在少数，如果说程序员不能在相应的时间里（并不是开会所说的时间）完成相应难度的任务，那么这个程序员本身就是不可靠的，那剩下的就没有讨论的意义。所以在讨论之前，我们都至少能够相信程序员是可以靠的住的（虽然代码性能和优化上不会太完美）。

当程序员这一方面没有问题之后，又是什么导致产品出现走下坡路的局面呢？我个人认为是沟通和计划，一个好的产品一定要有一个好的计划，并不能只局限于（或者说着重于）所谓的“快速发布”和“敏捷开发”，如果在整个团队中，使用了错误的“敏捷开发”并以“快速发布”作为指导的话，那么这个产品肯定会有局限性，因为速度和质量并不能完全的达到一致。

很简单，一个程序员可以一周时间开发一个产品，但是不代表这个产品就能够发布或者上线，因为无论是多么好的程序员，总会犯一些这样那样的错误，甚至还会有手抖的情况（比如多打了一个i或者之类的），那么就要花时间去修复和优化，但是产品人员和一些运营的人员可能不会理解，因为从他们的呈现的结果来看，他们的测试只是针对部分的功能进行测试，比如点了之后能不能用，能不能正确的安装，能不能跨平台等，所以他们的思考方式是从一个外在的而不是内在的因素去考虑，而程序员可能更多的是在扩展性，可持续性和维护性去考虑的。所以产品可能会觉得这个东西可以马上发布（甚至今天下午就能发布，只是有一些很小很小很小的问题），甚至认为做完一个产品就等于做好一个产品，这是非常不正确的。但是对于程序这边，一个小问题可能会有很多改动，甚至会造成重构等。所以，肯定是会有冲突的。

那么出了这种问题（而这种问题是会经常出现的，并不是一个团队存在的，可以说是几乎所有的团队都有这样的情况），一般如何解决呢。我觉得国内的一些公司主要是这样去解决的，因为产品的时间是一定的，几乎可以说是不能变的，那么就要从程序上改变，于是快速更改和hot fix就来的特别的多，那么这样几乎无法保证程序的质量，那么在后期的维护中，这个程序将会是一个重大的隐患，很可能在某一天就忽然爆发，然后危害整个产品，这样不仅危害到整个公司，整个团队，产品部门，甚至危害到程序员本身（和生存），于是就有了程序员的坚持问题。

这个时候，我认为程序员是应该坚持自己的一些“职业操守”的，也是我想说的一个关于程序员坚守的思考。程序员首先应该做的是考虑这款产品的持久性，如果自己还想在这里混下去，还想有更多的空间提高，那么就需要坚持这个职业操守，因为只有坚持了职业操守，那么产品的看不见的部分就能够更有持续性，维护性，提高整个团队的维护性能，也就间接的节约了成本，从而发挥了一个“好的”程序员的价值，也让自己的生存更具有持续性。

当然，这么说是很容易的，做起来很难，因为毕竟产品这一边肯定是有一个固定的计划的，就像我原来开发一些浏览器插件一样，况且每个人的想法也不同，比如要业绩，写Daily report的时候需要写一些东西才行，那么就需要逼着一些相关人员完成相关工作，这个时候很容易出现讨论（甚至争论）的情形，如果这个时候妥协进而放弃代码上的职业操守，那么很容易就会出现产品走下坡路和失败的情况，当然，如果不遵守，甚至可能出现争吵，团队内讧等情况，这样对项目更不好。

所以，在一定条件的允许下（例如公司氛围，团队氛围和公司的导向），如果公司愿意花更多的时间在产品质量上，而不是在产品速度上，那么程序员可以在一定程度上进行团队内部的讨论，然后和产品以及上级进行讨论，规划；如果公司更愿意执行“快速发布”，那么虽然这不是你我所想看到的，但是也只能执行，也就是说在这种公司去说程序员的职业操守是非常无聊的，简直就等于说废话，所以如果这样，那么没办法，该怎么做就怎么做（这样就会导致程序员想：反正也不是我的代码。导致质量下降），干活完了回家。

不过，相比之下，我更觉得程序员是有责任和义务对项目负责的，也就是说，无论公司的性质和氛围如何，好的程序员都应该提出自己的想法然后尽量的去实践，去说服其他相关人员，这样不仅能够让自己学到东西，也能够提高产品质量，这是大家都愿意看到的。

在实际工作中，我也经常遇到这样的问题，很多时候我选择了妥协，即妥协于产品和时间，虽然很多时候这个时间规划并不是很正确。妥协的直接结果就是我放弃了代码的复用和拆分，性能上的优化的考虑和性能上的测试，现在想想是非常不正确的，虽然某一个角度来说完成一个还不错的任务（及时发布），但是真正做的好不好和以后会不会有问题，只有我自己知道。也随着时间的增长和负责的项目越来越多，越来越大，我也更加深切的体会到“职业操守”对程序员来说是多么的重要。

所以，无论在任何项目，任何产品的开发或者是迭代过程中，都应该找到一个最好的切入点和切入方式，在一定的程度上尽量的保证程序员的职业操守的执行和坚持，是对于程序员来说最难实现，但是是最重要的。当然，一开始的计划和讨论也是非常必要的，虽然这不是我们讨论的范围（我们只讨论出现了这种情况下，程序员应该如何去做），而且也没有一个人，一个团队能够完整的规划好项目时间，说到哪一天就一定能发布。虽然，这种事情经常发生，也没有一个很好的解决方案，但是我希望自己以后能够在这方面多做努力，也希望这个行业的同行们多做努力，改善现在这样的整体环境和行业规范。让产品能够在一个良性的循环中逐渐成长。]]></description>
			<content:encoded><![CDATA[<p>已经工作了很长时间，一直也没有说一下这个“<strong>关于程序员坚守的思考</strong>”的问题，这个问题不是针对现在的公司，只是我这么长时间来工作的一些心得，特别是关于做为一个程序员一些心得。</p>
<p>在产品开发过程中，肯定是会有不同的人承担不同的职责并在团队中做自己相应的任务，每个人的目的都不同，比如产品的目的是要尽快的发布产品，而程序员的目的是要写出高质量的代码等等。实际上，写出高质量的代码并不是一件很难的事情，随着经验的增长和阅历的丰富，高质量的代码并不是一个难以攀爬的高峰，但是为什么产品会出现越来越慢或者越来越差的局面呢，我觉得这是有几个因素造成的。</p>
<p>首先是程序员的能力，虽然我们这个地方主要不会探讨程序员的能力。因为我们首先将程序员当成是有责任心，能力可佳的人，至少这样的人不在少数，如果说程序员不能在相应的时间里（并不是开会所说的时间）完成相应难度的任务，那么这个程序员本身就是不可靠的，那剩下的就没有讨论的意义。所以在讨论之前，我们都至少能够相信程序员是可以靠的住的（虽然代码性能和优化上不会太完美）。</p>
<p>当程序员这一方面没有问题之后，又是什么导致产品出现走下坡路的局面呢？我个人认为是沟通和计划，一个好的产品一定要有一个好的计划，并不能只局限于（或者说着重于）所谓的“快速发布”和“敏捷开发”，如果在整个团队中，使用了错误的“敏捷开发”并以“快速发布”作为指导的话，那么这个产品肯定会有局限性，因为速度和质量并不能完全的达到一致。</p>
<p>很简单，一个程序员可以一周时间开发一个产品，但是不代表这个产品就能够发布或者上线，因为无论是多么好的程序员，总会犯一些这样那样的错误，甚至还会有手抖的情况（比如多打了一个i或者之类的），那么就要花时间去修复和优化，但是产品人员和一些运营的人员可能不会理解，因为从他们的呈现的结果来看，他们的测试只是针对部分的功能进行测试，比如点了之后能不能用，能不能正确的安装，能不能跨平台等，所以他们的思考方式是从一个外在的而不是内在的因素去考虑，而程序员可能更多的是在扩展性，可持续性和维护性去考虑的。所以产品可能会觉得这个东西可以马上发布（甚至今天下午就能发布，只是有一些很小很小很小的问题），甚至认为做完一个产品就等于做好一个产品，这是非常不正确的。但是对于程序这边，一个小问题可能会有很多改动，甚至会造成重构等。所以，肯定是会有冲突的。</p>
<p>那么出了这种问题（而这种问题是会经常出现的，并不是一个团队存在的，可以说是几乎所有的团队都有这样的情况），一般如何解决呢。我觉得国内的一些公司主要是这样去解决的，因为产品的时间是一定的，几乎可以说是不能变的，那么就要从程序上改变，于是快速更改和hot fix就来的特别的多，那么这样几乎无法保证程序的质量，那么在后期的维护中，这个程序将会是一个重大的隐患，很可能在某一天就忽然爆发，然后危害整个产品，这样不仅危害到整个公司，整个团队，产品部门，甚至危害到程序员本身（和生存），于是就有了程序员的坚持问题。</p>
<p>这个时候，我认为程序员是应该坚持自己的一些“职业操守”的，也是我想说的一个关于程序员坚守的思考。程序员首先应该做的是考虑这款产品的持久性，如果自己还想在这里混下去，还想有更多的空间提高，那么就需要坚持这个职业操守，因为只有坚持了职业操守，那么产品的看不见的部分就能够更有持续性，维护性，提高整个团队的维护性能，也就间接的节约了成本，从而发挥了一个“好的”程序员的价值，也让自己的生存更具有持续性。</p>
<p>当然，这么说是很容易的，做起来很难，因为毕竟产品这一边肯定是有一个固定的计划的，就像我原来开发一些浏览器插件一样，况且每个人的想法也不同，比如要业绩，写Daily report的时候需要写一些东西才行，那么就需要逼着一些相关人员完成相关工作，这个时候很容易出现讨论（甚至争论）的情形，如果这个时候妥协进而放弃代码上的职业操守，那么很容易就会出现产品走下坡路和失败的情况，当然，如果不遵守，甚至可能出现争吵，团队内讧等情况，这样对项目更不好。</p>
<p>所以，在一定条件的允许下（例如公司氛围，团队氛围和公司的导向），如果公司愿意花更多的时间在产品质量上，而不是在产品速度上，那么程序员可以在一定程度上进行团队内部的讨论，然后和产品以及上级进行讨论，规划；如果公司更愿意执行“快速发布”，那么虽然这不是你我所想看到的，但是也只能执行，也就是说在这种公司去说程序员的职业操守是非常无聊的，简直就等于说废话，所以如果这样，那么没办法，该怎么做就怎么做（这样就会导致程序员想：反正也不是我的代码。导致质量下降），干活完了回家。</p>
<p>不过，相比之下，我更觉得程序员是有责任和义务对项目负责的，也就是说，无论公司的性质和氛围如何，好的程序员都应该提出自己的想法然后尽量的去实践，去说服其他相关人员，这样不仅能够让自己学到东西，也能够提高产品质量，这是大家都愿意看到的。</p>
<p>在实际工作中，我也经常遇到这样的问题，很多时候我选择了妥协，即妥协于产品和时间，虽然很多时候这个时间规划并不是很正确。妥协的直接结果就是我放弃了代码的复用和拆分，性能上的优化的考虑和性能上的测试，现在想想是非常不正确的，虽然某一个角度来说完成一个还不错的任务（及时发布），但是真正做的好不好和以后会不会有问题，只有我自己知道。也随着时间的增长和负责的项目越来越多，越来越大，我也更加深切的体会到“职业操守”对程序员来说是多么的重要。</p>
<p>所以，无论在任何项目，任何产品的开发或者是迭代过程中，都应该找到一个最好的切入点和切入方式，在一定的程度上尽量的保证程序员的职业操守的执行和坚持，是对于程序员来说最难实现，但是是最重要的。当然，一开始的计划和讨论也是非常必要的，虽然这不是我们讨论的范围（我们只讨论出现了这种情况下，程序员应该如何去做），而且也没有一个人，一个团队能够完整的规划好项目时间，说到哪一天就一定能发布。虽然，这种事情经常发生，也没有一个很好的解决方案，但是我希望自己以后能够在这方面多做努力，也希望这个行业的同行们多做努力，改善现在这样的整体环境和行业规范。让产品能够在一个良性的循环中逐渐成长。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jguoer.com/blog/index.php/archives/1083/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>HTML5和CSS3以及菜单的编写</title>
		<link>http://www.jguoer.com/blog/index.php/archives/130</link>
		<comments>http://www.jguoer.com/blog/index.php/archives/130#comments</comments>
		<pubDate>Tue, 02 Mar 2010 13:07:00 +0000</pubDate>
		<dc:creator>诡异的西红柿</dc:creator>
				<category><![CDATA[Web前端]]></category>
		<category><![CDATA[软件开发]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[HTML5]]></category>

		<guid isPermaLink="false">/post/2010/03/02/HTML5-CSS3-Menu-And-Menuitem.aspx</guid>
		<description><![CDATA[其实很早就想写HTML5和CSS3的文章了，但是一直都没什么时间写，最近闲下来了，于是就写一下HTML5和CSS3的文章。HTML5出来了有一段时间了，各个主流浏览器基本上都能够支持HTML5，HTML5能够为我们做很多事情，并且轻松的就能够实现非常酷的效果。我们不仅能在网页前端制作上面可以使用HTML5和CSS3，我们还能够在浏览器插件中使用HTML5和CSS3（因为Chrome和Firefo浏览器都支持HTML5），那么我们不如来尝试写一个HTML5的网页或插件。

不过写之前，我们要看看为什么要使用HTML5。关于HTML5的概念，可以去<a href="http://zh.wikipedia.org/wiki/HTML_5" target="_blank">这里</a>看。

我们一般写一个HTML网页的时候，基本上会写如下代码。
<div class="code">
<div><span style="color: #0000ff;">&#60;</span><span style="color: #800000;">div </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="blog"</span><span style="color: #0000ff;">&#62;</span><span style="color: #000000;">

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">div </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="sidebar"</span><span style="color: #ff0000;"> class</span><span style="color: #0000ff;">="sidebarmain"</span><span style="color: #0000ff;">&#62;</span><span style="color: #000000;"> </span>

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&#62;</span><span style="color: #000000;"> </span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">div </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="content"</span><span style="color: #0000ff;">&#62;</span><span style="color: #000000;"> </span>

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&#62;</span><span style="color: #000000;"> </span>

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&#62;</span>

</span></div>
</div>
我们可以看到上面的代码是通过Table进化过来的，曾经有一段时间，网页开发人员喜欢使用Table去布局，但是现在，网站开发人员更喜欢使用div去布局，原因就是Table布局不够语义化，也不够方便。使用div去布局就能够语义化，比如 id，class。不过随着网络的发展，这样也有一些坏处，比如，重复的去写id让这个div更有意义，比如有一个id，又包括一个class等等。其实，最主要的还是语义上不清楚，对搜索引擎的优化不够好。那么有了HTML5，我们就可以写成如下代码。
<div class="code">
<div><span style="color: #000000;">&#60;</span><span style="color: #000000;">blog</span><span style="color: #000000;">&#62;</span><span style="color: #000000;">

<span style="color: #000000;">&#60;</span><span style="color: #000000;">sidebar</span><span style="color: #000000;">&#62;</span><span style="color: #000000;"> </span>

<span style="color: #000000;">&#60;/</span><span style="color: #000000;">sidebar</span><span style="color: #000000;">&#62;</span><span style="color: #000000;"> </span>

<span style="color: #000000;">&#60;</span><span style="color: #000000;">content</span><span style="color: #000000;">&#62;</span>

<span style="color: #000000;">&#60;/</span><span style="color: #000000;">content</span><span style="color: #000000;">&#62;</span>

<span style="color: #000000;">&#60;/</span><span style="color: #000000;">blog</span><span style="color: #000000;">&#62;</span>

</span></div>
</div>
按照上面的方式，我们的代码就更具备意义，所以，HTML5就是为我们解决了这样一个问题，我们无论在写网站还是写浏览器插件的时候，语义不仅能够方便我们的搜索引擎去抓取页面内容，另外一方面更能够方便我们去维护，因为语义，我们写CSS代码也更加简单。
<div class="code">
<div><span style="color: #800000;">blog

<span style="color: #000000;">{</span>

color

<span style="color: #000000;">:</span><span style="color: #0000ff;">black</span><span style="color: #000000;">;</span>

<span style="color: #000000;">}</span>

blog sidebar

<span style="color: #000000;">{</span>

float

<span style="color: #000000;">:</span><span style="color: #0000ff;">right</span><span style="color: #000000;">;</span>

<span style="color: #000000;">}</span>

blog content

<span style="color: #000000;">{</span>

float

<span style="color: #000000;">:</span><span style="color: #0000ff;">right</span><span style="color: #000000;">;</span>

<span style="color: #000000;">}</span>

</span></div>
</div>
这样，我们的CSS代码也更具有语义性了。好了，说了这么多，简单的来说，使用HTML和CSS3，我们可以去掉所有的class属性和id属性，让分层更加清晰，让代码更加可读，让结构更加简单。

说了这么多，终于可以开始写代码了，这里我写的是一个Chrome插件，不过可以用浏览器去访问，很简单，做的一个下拉菜单，有三种效果，我这里截取了两种效果的图。先看图。
<p style="text-align: center;"><img src="/blog/wp-content/uploads/2010/3/menu1.png" alt="" /></p>
<p style="text-align: center;"><img src="/blog/wp-content/uploads/2010/3/menu3.png" alt="" /></p>
好了，我们有了目标，就写相应的代码把。首先写HTML代码。
<div class="code">
<div><span style="color: #0000ff;">&#60;!</span><span style="color: #ff00ff;">DOCTYPE html</span><span style="color: #0000ff;">&#62;</span><span style="color: #000000;">

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">html</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">head</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">title</span><span style="color: #0000ff;">&#62;</span><span style="color: #000000;">Amazon Button</span><span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">title</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">script </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="text/javascript"</span><span style="color: #ff0000;"> src</span><span style="color: #0000ff;">="js/jquery.js"</span><span style="color: #0000ff;">&#62;&#60;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">script </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="text/javascript"</span><span style="color: #ff0000;"> src</span><span style="color: #0000ff;">="js/main.js"</span><span style="color: #0000ff;">&#62;&#60;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">link </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="text/css"</span><span style="color: #ff0000;"> href</span><span style="color: #0000ff;">="css/css.css"</span><span style="color: #ff0000;"> rel</span><span style="color: #0000ff;">="stylesheet"</span><span style="color: #ff0000;"> </span><span style="color: #0000ff;">/&#62;</span>

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">head</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">body</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">rmenu</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">rmenupopup</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">tmenu</span><span style="color: #0000ff;">&#62;</span>

Bestsellers

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">menupopup</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">tmenu</span><span style="color: #0000ff;">&#62;</span>

Bestsellers Item1

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">menupopup</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">menuitem</span><span style="color: #0000ff;">&#62;</span>

Google

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">menuitem</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">menupopup</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">tmenu</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">menuitem</span><span style="color: #0000ff;">&#62;</span>

Bestsellers Item2

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">menuitem</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">menuitem</span><span style="color: #0000ff;">&#62;</span>

Bestsellers Item3

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">menuitem</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">menupopup</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">tmenu</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;</span><span style="color: #800000;">tmenu</span><span style="color: #0000ff;">&#62;</span>

Bestsellers

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">tmenu</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">rmenupopup</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">rmenu</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">body</span><span style="color: #0000ff;">&#62;</span>

<span style="color: #0000ff;">&#60;/</span><span style="color: #800000;">html</span><span style="color: #0000ff;">&#62;</span>

</span></div>
</div>
不用我多说，你也应该知道是什么意思了，tmenu是菜单，menupopup是菜单一个容器，menuitem就是每个菜单项了。OK，现在我们再来写CSS代码。
<div class="code">
<div><span style="color: #800000;">body

<span style="color: #000000;">{</span>

margin

<span style="color: #000000;">:</span><span style="color: #0000ff;">0px</span><span style="color: #000000;">;</span>

font-size

<span style="color: #000000;">:</span><span style="color: #0000ff;">12px</span><span style="color: #000000;">;</span>

font-family

<span style="color: #000000;">:</span><span style="color: #0000ff;">arial</span><span style="color: #000000;">;</span>

width

<span style="color: #000000;">:</span><span style="color: #0000ff;">400px</span><span style="color: #000000;">;</span>

height

<span style="color: #000000;">:</span><span style="color: #0000ff;">300px</span><span style="color: #000000;">;</span>

<span style="color: #000000;">}</span>

rmenu,rmenupopup,tmenu,menuitem,menupopup

<span style="color: #000000;">{</span>

display

<span style="color: #000000;">:</span><span style="color: #0000ff;">block</span><span style="color: #000000;">;</span>

margin

<span style="color: #000000;">:</span><span style="color: #0000ff;">0px</span><span style="color: #000000;">;</span>

color

<span style="color: #000000;">:</span><span style="color: #0000ff;">black</span><span style="color: #000000;">;</span>

<span style="color: #000000;">}</span>

tmenu,menuitem

<span style="color: #000000;">{</span>

background

<span style="color: #000000;">:</span><span style="color: #0000ff;">#f0f0f0</span><span style="color: #000000;">;</span>

border-bottom

<span style="color: #000000;">:</span><span style="color: #0000ff;">1px solid #e0e0e0</span><span style="color: #000000;">;</span>

border-top

<span style="color: #000000;">:</span><span style="color: #0000ff;">1px solid white</span><span style="color: #000000;">;</span>

min-width

<span style="color: #000000;">:</span><span style="color: #0000ff;">200px</span><span style="color: #000000;">;</span>

padding

<span style="color: #000000;">:</span><span style="color: #0000ff;">5px</span><span style="color: #000000;">;</span>

max-width

<span style="color: #000000;">:</span><span style="color: #0000ff;">500px</span><span style="color: #000000;">;</span>

<span style="color: #000000;">}</span>

tmenu

<span style="color: #000000;">{</span>

background

<span style="color: #000000;">:</span><span style="color: #0000ff;">#f0f0f0 url("../images/dropdown.png") no-repeat center right</span><span style="color: #000000;">;</span>

<span style="color: #000000;">}</span>

menupopup

<span style="color: #000000;">{</span>

border

<span style="color: #000000;">:</span><span style="color: #0000ff;">1px solid #ccc</span><span style="color: #000000;">;</span>

<span style="color: #000000;">}</span>

menupopup

<span style="color: #000000;">{</span>

display

<span style="color: #000000;">:</span><span style="color: #0000ff;">none</span><span style="color: #000000;">;</span>

margin-left

<span style="color: #000000;">:</span><span style="color: #0000ff;">10px</span><span style="color: #000000;">;</span>

<span style="color: #000000;">}</span>

a

<span style="color: #000000;">{</span>

text-decoration

<span style="color: #000000;">:</span><span style="color: #0000ff;">none</span><span style="color: #000000;">;</span>

color

<span style="color: #000000;">:</span><span style="color: #0000ff;">black</span><span style="color: #000000;">;</span>

<span style="color: #000000;">}</span>

</span></div>
</div>
CSS代码也是非常好理解的，现在我们就要写菜单的相应的JS代码了，这里我就不贴出JS代码了，代码可以从源代码中下载得到。

小结

其实最后我们从编程实例中可以看出，虽然HTML5和CSS3对开发人员来说没有特别好的编码方面的提升，但是在效果上和语义化上面有了很大的提升，节约了开发人员很多步骤。也随着HTML5的发展，在线视频，在线游戏，在线3D的提出和实现，可以看出未来网络的发展越来越快，越来越丰富，真正的基于浏览器的网络游戏和3D游戏也会随着时间和浏览器的支持流行起来，到时候网络应用和桌面应用的界限也会越来越模糊。

代码下载

<a href="/blog/wp-content/uploads/2010/3/Prototype.zip">Prototype.zip (183.52 kb)</a>]]></description>
			<content:encoded><![CDATA[<p>其实很早就想写HTML5和CSS3的文章了，但是一直都没什么时间写，最近闲下来了，于是就写一下HTML5和CSS3的文章。HTML5出来了有一段时间了，各个主流浏览器基本上都能够支持HTML5，HTML5能够为我们做很多事情，并且轻松的就能够实现非常酷的效果。我们不仅能在网页前端制作上面可以使用HTML5和CSS3，我们还能够在浏览器插件中使用HTML5和CSS3（因为Chrome和Firefo浏览器都支持HTML5），那么我们不如来尝试写一个HTML5的网页或插件。</p>
<p>不过写之前，我们要看看为什么要使用HTML5。关于HTML5的概念，可以去<a href="http://zh.wikipedia.org/wiki/HTML_5" target="_blank">这里</a>看。</p>
<p>我们一般写一个HTML网页的时候，基本上会写如下代码。</p>
<div class="code">
<div><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">=&#8221;blog&#8221;</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">=&#8221;sidebar&#8221;</span><span style="color: #ff0000;"> class</span><span style="color: #0000ff;">=&#8221;sidebarmain&#8221;</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"> </span></p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"> </span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">div </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">=&#8221;content&#8221;</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"> </span></p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"> </span></p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000ff;">&gt;</span></p>
<p></span></div>
</div>
<p>我们可以看到上面的代码是通过Table进化过来的，曾经有一段时间，网页开发人员喜欢使用Table去布局，但是现在，网站开发人员更喜欢使用div去布局，原因就是Table布局不够语义化，也不够方便。使用div去布局就能够语义化，比如 id，class。不过随着网络的发展，这样也有一些坏处，比如，重复的去写id让这个div更有意义，比如有一个id，又包括一个class等等。其实，最主要的还是语义上不清楚，对搜索引擎的优化不够好。那么有了HTML5，我们就可以写成如下代码。</p>
<div class="code">
<div><span style="color: #000000;">&lt;</span><span style="color: #000000;">blog</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"></p>
<p><span style="color: #000000;">&lt;</span><span style="color: #000000;">sidebar</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> </span></p>
<p><span style="color: #000000;">&lt;/</span><span style="color: #000000;">sidebar</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> </span></p>
<p><span style="color: #000000;">&lt;</span><span style="color: #000000;">content</span><span style="color: #000000;">&gt;</span></p>
<p><span style="color: #000000;">&lt;/</span><span style="color: #000000;">content</span><span style="color: #000000;">&gt;</span></p>
<p><span style="color: #000000;">&lt;/</span><span style="color: #000000;">blog</span><span style="color: #000000;">&gt;</span></p>
<p></span></div>
</div>
<p>按照上面的方式，我们的代码就更具备意义，所以，HTML5就是为我们解决了这样一个问题，我们无论在写网站还是写浏览器插件的时候，语义不仅能够方便我们的搜索引擎去抓取页面内容，另外一方面更能够方便我们去维护，因为语义，我们写CSS代码也更加简单。</p>
<div class="code">
<div><span style="color: #800000;">blog</p>
<p><span style="color: #000000;">{</span></p>
<p>color</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">black</span><span style="color: #000000;">;</span></p>
<p><span style="color: #000000;">}</span></p>
<p>blog sidebar</p>
<p><span style="color: #000000;">{</span></p>
<p>float</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">right</span><span style="color: #000000;">;</span></p>
<p><span style="color: #000000;">}</span></p>
<p>blog content</p>
<p><span style="color: #000000;">{</span></p>
<p>float</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">right</span><span style="color: #000000;">;</span></p>
<p><span style="color: #000000;">}</span></p>
<p></span></div>
</div>
<p>这样，我们的CSS代码也更具有语义性了。好了，说了这么多，简单的来说，使用HTML和CSS3，我们可以去掉所有的class属性和id属性，让分层更加清晰，让代码更加可读，让结构更加简单。</p>
<p>说了这么多，终于可以开始写代码了，这里我写的是一个Chrome插件，不过可以用浏览器去访问，很简单，做的一个下拉菜单，有三种效果，我这里截取了两种效果的图。先看图。</p>
<p style="text-align: center;"><img src="/blog/wp-content/uploads/2010/3/menu1.png" alt="" /></p>
<p style="text-align: center;"><img src="/blog/wp-content/uploads/2010/3/menu3.png" alt="" /></p>
<p>好了，我们有了目标，就写相应的代码把。首先写HTML代码。</p>
<div class="code">
<div><span style="color: #0000ff;">&lt;!</span><span style="color: #ff00ff;">DOCTYPE html</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">html</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">head</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">title</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">Amazon Button</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">title</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">=&#8221;text/javascript&#8221;</span><span style="color: #ff0000;"> src</span><span style="color: #0000ff;">=&#8221;js/jquery.js&#8221;</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">script </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">=&#8221;text/javascript&#8221;</span><span style="color: #ff0000;"> src</span><span style="color: #0000ff;">=&#8221;js/main.js&#8221;</span><span style="color: #0000ff;">&gt;&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">link </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">=&#8221;text/css&#8221;</span><span style="color: #ff0000;"> href</span><span style="color: #0000ff;">=&#8221;css/css.css&#8221;</span><span style="color: #ff0000;"> rel</span><span style="color: #0000ff;">=&#8221;stylesheet&#8221;</span><span style="color: #ff0000;"> </span><span style="color: #0000ff;">/&gt;</span></p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">head</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">body</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">rmenu</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">rmenupopup</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">tmenu</span><span style="color: #0000ff;">&gt;</span></p>
<p>Bestsellers</p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">menupopup</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">tmenu</span><span style="color: #0000ff;">&gt;</span></p>
<p>Bestsellers Item1</p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">menupopup</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">menuitem</span><span style="color: #0000ff;">&gt;</span></p>
<p>Google</p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">menuitem</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">menupopup</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">tmenu</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">menuitem</span><span style="color: #0000ff;">&gt;</span></p>
<p>Bestsellers Item2</p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">menuitem</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">menuitem</span><span style="color: #0000ff;">&gt;</span></p>
<p>Bestsellers Item3</p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">menuitem</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">menupopup</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">tmenu</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">tmenu</span><span style="color: #0000ff;">&gt;</span></p>
<p>Bestsellers</p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">tmenu</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">rmenupopup</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">rmenu</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">body</span><span style="color: #0000ff;">&gt;</span></p>
<p><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">html</span><span style="color: #0000ff;">&gt;</span></p>
<p></span></div>
</div>
<p>不用我多说，你也应该知道是什么意思了，tmenu是菜单，menupopup是菜单一个容器，menuitem就是每个菜单项了。OK，现在我们再来写CSS代码。</p>
<div class="code">
<div><span style="color: #800000;">body</p>
<p><span style="color: #000000;">{</span></p>
<p>margin</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">0px</span><span style="color: #000000;">;</span></p>
<p>font-size</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">12px</span><span style="color: #000000;">;</span></p>
<p>font-family</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">arial</span><span style="color: #000000;">;</span></p>
<p>width</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">400px</span><span style="color: #000000;">;</span></p>
<p>height</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">300px</span><span style="color: #000000;">;</span></p>
<p><span style="color: #000000;">}</span></p>
<p>rmenu,rmenupopup,tmenu,menuitem,menupopup</p>
<p><span style="color: #000000;">{</span></p>
<p>display</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">block</span><span style="color: #000000;">;</span></p>
<p>margin</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">0px</span><span style="color: #000000;">;</span></p>
<p>color</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">black</span><span style="color: #000000;">;</span></p>
<p><span style="color: #000000;">}</span></p>
<p>tmenu,menuitem</p>
<p><span style="color: #000000;">{</span></p>
<p>background</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">#f0f0f0</span><span style="color: #000000;">;</span></p>
<p>border-bottom</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">1px solid #e0e0e0</span><span style="color: #000000;">;</span></p>
<p>border-top</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">1px solid white</span><span style="color: #000000;">;</span></p>
<p>min-width</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">200px</span><span style="color: #000000;">;</span></p>
<p>padding</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">5px</span><span style="color: #000000;">;</span></p>
<p>max-width</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">500px</span><span style="color: #000000;">;</span></p>
<p><span style="color: #000000;">}</span></p>
<p>tmenu</p>
<p><span style="color: #000000;">{</span></p>
<p>background</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">#f0f0f0 url(&#8220;../images/dropdown.png&#8221;) no-repeat center right</span><span style="color: #000000;">;</span></p>
<p><span style="color: #000000;">}</span></p>
<p>menupopup</p>
<p><span style="color: #000000;">{</span></p>
<p>border</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">1px solid #ccc</span><span style="color: #000000;">;</span></p>
<p><span style="color: #000000;">}</span></p>
<p>menupopup</p>
<p><span style="color: #000000;">{</span></p>
<p>display</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">none</span><span style="color: #000000;">;</span></p>
<p>margin-left</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">10px</span><span style="color: #000000;">;</span></p>
<p><span style="color: #000000;">}</span></p>
<p>a</p>
<p><span style="color: #000000;">{</span></p>
<p>text-decoration</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">none</span><span style="color: #000000;">;</span></p>
<p>color</p>
<p><span style="color: #000000;">:</span><span style="color: #0000ff;">black</span><span style="color: #000000;">;</span></p>
<p><span style="color: #000000;">}</span></p>
<p></span></div>
</div>
<p>CSS代码也是非常好理解的，现在我们就要写菜单的相应的JS代码了，这里我就不贴出JS代码了，代码可以从源代码中下载得到。</p>
<p>小结</p>
<p>其实最后我们从编程实例中可以看出，虽然HTML5和CSS3对开发人员来说没有特别好的编码方面的提升，但是在效果上和语义化上面有了很大的提升，节约了开发人员很多步骤。也随着HTML5的发展，在线视频，在线游戏，在线3D的提出和实现，可以看出未来网络的发展越来越快，越来越丰富，真正的基于浏览器的网络游戏和3D游戏也会随着时间和浏览器的支持流行起来，到时候网络应用和桌面应用的界限也会越来越模糊。</p>
<p>代码下载</p>
<p><a href="/blog/wp-content/uploads/2010/3/Prototype.zip">Prototype.zip (183.52 kb)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jguoer.com/blog/index.php/archives/130/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ASP.NET开发技术大全源代码</title>
		<link>http://www.jguoer.com/blog/index.php/archives/132</link>
		<comments>http://www.jguoer.com/blog/index.php/archives/132#comments</comments>
		<pubDate>Thu, 25 Feb 2010 14:07:00 +0000</pubDate>
		<dc:creator>诡异的西红柿</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[倒带人生]]></category>
		<category><![CDATA[小分享]]></category>
		<category><![CDATA[软件开发]]></category>
		<category><![CDATA[源代码]]></category>

		<guid isPermaLink="false">/post/2010/02/25/Code-Of-My-Book.aspx</guid>
		<description><![CDATA[这是一本一年多以前我写的一本书，但是没想到过了一段时间还是有人需要，这本书估计已经下市了，很多人直接给我发短信说买不到了，然后说找不到源代码以及光盘里的东西。我这里有一本作者用书，所以我这里有一点源代码，由于一开始不在我的手上，现在拿回来了，方便广大网友，所以就在这里提供源代码下载。本来有一个人说拿去做教材的，买不到书，说是要给他邮寄过去的，可惜我媳妇不想，于是作罢，对这个网友是非常不好意思，这里就提供源代码下载吧。

虽然这本书是我写的，但是有一年了，有很多网友还是会发邮件问我书的问题，我这本书是初学者的书，也是入门级别的，所以高手可以不需要看，然后对于入门的新手，我还是觉得能帮到别人一点算是一点，所以大家还是可以给我写邮件，不过注意基本的礼节，我也是要工作要吃饭会很忙的人，所以忙的时候不能解答问题，请见谅。书里面的内容和编写时间按照出版社要求所写，有错误或者有章节划分不好，也实在没有办法。

这本书可以到<a href="http://product.dangdang.com/product.aspx?product_id=20574546" target="_blank"><strong>这里</strong></a>购买，源代码可以在<a href="http://dl.dropbox.com/u/2231425/codes.zip" target="_blank"><strong>这里</strong></a>下载。（说不定过一段时间就没了，没了的话再联系我，我再放上去）]]></description>
			<content:encoded><![CDATA[<p>这是一本一年多以前我写的一本书，但是没想到过了一段时间还是有人需要，这本书估计已经下市了，很多人直接给我发短信说买不到了，然后说找不到源代码以及光盘里的东西。我这里有一本作者用书，所以我这里有一点源代码，由于一开始不在我的手上，现在拿回来了，方便广大网友，所以就在这里提供源代码下载。本来有一个人说拿去做教材的，买不到书，说是要给他邮寄过去的，可惜我媳妇不想，于是作罢，对这个网友是非常不好意思，这里就提供源代码下载吧。</p>
<p>虽然这本书是我写的，但是有一年了，有很多网友还是会发邮件问我书的问题，我这本书是初学者的书，也是入门级别的，所以高手可以不需要看，然后对于入门的新手，我还是觉得能帮到别人一点算是一点，所以大家还是可以给我写邮件，不过注意基本的礼节，我也是要工作要吃饭会很忙的人，所以忙的时候不能解答问题，请见谅。书里面的内容和编写时间按照出版社要求所写，有错误或者有章节划分不好，也实在没有办法。</p>
<p>这本书可以到<a href="http://product.dangdang.com/product.aspx?product_id=20574546" target="_blank"><strong>这里</strong></a>购买，源代码可以在<a href="http://dl.dropbox.com/u/2231425/codes.zip" target="_blank"><strong>这里</strong></a>下载。（说不定过一段时间就没了，没了的话再联系我，我再放上去）</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jguoer.com/blog/index.php/archives/132/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

