<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.2" -->
<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/"
	>

<channel>
	<title>前沿视频教室-提供最好的视频教程-CSS-Javascirpt-Web-设计与开发</title>
	<link>http://learning.artech.cn</link>
	<description>学习在前沿！这里是“前沿视频教室”，在这里您可以找到关于各种网页设计/网站开发/Flash动画相关的内容，而且我们都通过视频演示的方式，直观地向您讲解！包括CSS/Javascript/Flash/Dreamweaver/Fireworks/Photoshop等软件的使用和技巧!</description>
	<pubDate>Wed, 09 Dec 2009 12:55:07 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2</generator>
	<language>en</language>
			<item>
		<title>Web开发杂谈(10) —— 原型设计与工具</title>
		<link>http://learning.artech.cn/20091209.sketchflow-intro.html</link>
		<comments>http://learning.artech.cn/20091209.sketchflow-intro.html#comments</comments>
		<pubDate>Wed, 09 Dec 2009 11:20:28 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[Web开发杂谈]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20091209.sketchflow-intro.html</guid>
		<description><![CDATA[任何一个网站都是经过一定的过程，才能逐渐由头脑中的概念成为一个真正的网站的。一个网站的设计过程往往是需要经过大量的修改、甚至若干次的推翻重来，才可以达到最终的结果。今天... ]]></description>
			<content:encoded><![CDATA[<p>任何一个网站都是经过一定的过程，才能逐渐由头脑中的概念成为一个真正的网站的。一个网站的设计过程往往是需要经过大量的修改、甚至若干次的推翻重来，才可以达到最终的结果。今天来简单谈谈这个过程中使用的方法和工具。</p>
<h3>问题的背景</h3>
<p>在最初的设计阶段，最重要的一点是与客户进行良好而充分的沟通。尤其是<b>现在的网站功能越来越复杂，而客户往往只能描述一些非常抽像的概念、想法和特征</b>。</p>
<p>因此需要我们做设计和开发的人充分理解客户的想法，但是一个重要的问题是，我们如何验证我们是否真正理解了客户的想法呢？当然我们通常会写一些文档，作为与客户签订合同的附件。但是即使用再多的文字描述，毕竟客户看不到最终的效果，而最终开发出来的网站或系统如果不符合客户的心意，就是一件非常麻烦的事情了。要么为了符合客户的要求，而进行大量的修改工作，其中的成本是非常巨大的，而你向客户追加费用是很困难的事情了，即使客户同意，也不是件令人非常开心的事。要么就只能凑了，也许这并不是设计和开发公司的责任，但是毕竟问题发生了。</p>
<p>那么从比较理想的方式应该是如何的呢？显然，如果我们能够<b>在还没有真正开始投入大量人力进行设计和开发之前，就可以让用户看到最终的效果和功能</b>，那就是最好的了！这就是所谓的“原型设计”的作用。</p>
<p>我们用尽可能小的代价，把我们理解的用户需求表现出来，或者叫“模拟”出来，甚至用户可以实际操作，就好象这个系统已经做好了一样，这样将来做出来的系统和这个“原型”系统非常接近，那么在开发完成后在发现问题的可能性就小多了。</p>
<h3>静态原型</h3>
<p>因此，原型系统是非常重要而有效的一个手段，那么有什么好的方法来实现“原型”呢？</p>
<p>当然，最基本的方法就是手工绘制一些图纸了，此外，比如Fireworks软件中，提供了一些更为方便的进行原型设计的功能，但是这些方法和软件还是停留在“静态”展示的层面，本质上和手工绘制一些图给客户，进行纸上谈兵是一样的。</p>
<p>而现在网站的交互功能越来越强，一些基于Web的信息管理系统，操作起来就跟们更为复杂，比如各个页面之间的跳转，如果使用了Ajax等技术，页面还会局部刷新，如果都要用静态的图像来表达，实际上是非常困难的。</p>
<h3>SkecthFlow 增加原型系统的动态性 </h3>
<p>因此，如果我们可以方便地制作出，可以模拟最终的动态效果的原型，那么就好多了！这是基于这个原因，近年来出现了一些具有模拟效果的原型设计软件，比如我们以前介绍过的Axure RP Pro，不我实际使用过一两个项目以后，感觉这个工具还是不够方便。而今天介绍一个我刚刚开始使用的软件 SketchFlow，感觉非常棒！实际上这不是一个独立的软件，而是附属于 Expression Blend 的一部分。而 Expression Blend则是微软的 <a target="_blank" href="http://www.microsoft.com/china/expression/">Expression Studio</a> 套件中的一个。如果再往下说，就要到大名鼎鼎的 Silverlight （微软指望靠它和Flash大干一场呢）上了—— Expression Blend 正是用来设计和开发 Silverlight应用的软件，因此对于微软来说，这可是一个重头戏。</p>
<p>而在 Expression Blend 3 中，包括了一个部分叫做“SkechFlow”，我们今天要讲的就是它了。 因此现在这个软件的全称叫做“<a target="_blank" href="http://www.microsoft.com/china/expression/products/Sketchflow_Overview.aspx">Microsoft Expression 3 + SketchFlow</a>”，够长的名字。</p>
<p>Sketch 就是草图的意思，Flow就是流程的意思，因此合在一起，就是“流程草图”的意思。那么它具有什么用呢？</p>
<h3>SkecthFlow 的用途 </h3>
<p>首先，这个Blend这个软件本身就是可以绘制矢量图形和动画的，因此用它来绘制页面的草图是很方便的，比如假设我们要租一个网站，首先是一个登录页面，然后进入到一个内容页，我们就可以非常方便地绘制出如下的图形，注意这种风格是专门为此设计的草图风格，看起来就像是手绘的风格，主要的目的就是给用户展现的是页面的核心概念和功能，而不会是非常细节的样式。我个人非常喜欢这种风格，看起来分舒服。</p>
<p><img src='http://learning.artech.cn/wp-content/uploads/2009/12/sketchflow.png' alt='Sketchflow' /></p>
<p>当然，如果只是把图像绘制的看起来手绘风格，那么也就没有太的改进了，更更为重要的是，使用SketchFlow制作的网站原型，可以精确地模拟实际操作过程，比如上面图中，登录框中的用户名输入框、密码输入框、滑动条、选择框、按钮都是可以实际操作的，而且通过简单控制，就可以非常方便地使他实际工作起来。在比如，上面的右图中，“作者介绍”和“读者评价”部分，各有一个滚动条，而这些滚动条都是有实际作用的，因此使用这种方式制作出来的原型，可以使客户非常直观而精确地了解最终这个网站完成以后，会是什么样子的，这样如果他又不满意的地方，在一开始就可以明确地指出来，这样对于我们开发成本的控制就大有好处了。</p>
<p>此外，软件中给出了方便的导航图，以显示各个页面之间的导航关系，也非常清晰实用，如下图所示。</p>
<p><img src='http://learning.artech.cn/wp-content/uploads/2009/12/flow.png' alt='Sketchflow 2' /></p>
<p>有兴趣的读者可以在浏览器中实际看一下演示的效果，如果没有安装Silverlight插件的话，需要安装一下。<a target="_blank" href=" http://learning.artech.cn/uploads/blog-files/sketchflow/demo1.html">请点击这里查看实际效果</a>，在登录页面随意输入，然后按Login按钮，导航至内容页面，可以在左侧调整大小。</p>
<p>此外，SketchFlow还可以自动生成Word格式文档，包括目录、文字、导航图、各个页面都准备好了，这样稍作修改后，提供给客户交流，就非常方便，也非常专业了。如下图所示。</p>
<p><img src='http://learning.artech.cn/wp-content/uploads/2009/12/flwo2word.png' alt='Sketchflow 2 word' /></p>
<p>当然，这个软件的功能还远远不止于添加几个导航链接的功能，因为它本身用C#或者VB就可以进行深入而灵活的控制了，不过我自己也没有深入学习过Silverlight的开发，并不能说的非常清楚，此外这些操作并非几句话可以说清的了，有兴趣的读者，可以参看前不久的<a href="http://microsoftpdc.com/Sessions/CL23">微软开发者大会上关于 SketchFlow 的讲演</a>： http://microsoftpdc.com/Sessions/CL23 。讲演者说的英语不算快，还比较容易听懂，另外有很多屏幕操作，也很有帮助。</p>
<h3>本文小结</h3>
<p>今天重点介绍了两个问题，1）在实际开发之前，制作原型系统的重要性，以及能够给我们带来的好处。 2）使用 SketchFlow 可以比较方便地制作出高度模拟实际效果的原型系统，给我们带来很大的益处。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20091209.sketchflow-intro.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>如果无法在线播放本站的视频教程，请告知，谢谢</title>
		<link>http://learning.artech.cn/20091112.can-not-play.html</link>
		<comments>http://learning.artech.cn/20091112.can-not-play.html#comments</comments>
		<pubDate>Thu, 12 Nov 2009 03:16:56 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[本站信息]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20091112.can-not-play.html</guid>
		<description><![CDATA[前几天，我们使用的服务器提供商在技术上做了一些修改，导致本站上的一部分 FLV 格式的视频无法正常下载观看了，经过我们和服务商的技术人员联系，目前已经解决，从我们这里访问，可以... ]]></description>
			<content:encoded><![CDATA[<p>前几天，我们使用的服务器提供商在技术上做了一些修改，导致本站上的一部分 FLV 格式的视频无法正常下载观看了，经过我们和服务商的技术人员联系，目前已经解决，从我们这里访问，可以正常观看视频教程了，速度也不错，非常流畅。</p>
<p>如果您在观看的时候，无法正常在线播放的话，请在这里留言，说一下您遇到的现象，我们会进行检查，谢谢！</p>
<p>谢谢大家的支持！</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20091112.can-not-play.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Web开发杂谈(9) ——网站空间故障的排查</title>
		<link>http://learning.artech.cn/20091104.server-network-checking.html</link>
		<comments>http://learning.artech.cn/20091104.server-network-checking.html#comments</comments>
		<pubDate>Wed, 04 Nov 2009 06:59:53 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[Web开发杂谈]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20091104.server-network-checking.html</guid>
		<description><![CDATA[我们从去年6月份开始为我们的一些读者提供实际练兵的的虚拟主机空间——“学以致用”计划，现在有了不少的会员。本文主要是针对我们的会员遇到问题时参考来解决问题用的，如果您拥有... ]]></description>
			<content:encoded><![CDATA[<p>我们从去年6月份开始为我们的一些读者提供实际练兵的的<a target="_blank" href="http://talking.artech.cn/thread-1003-1-1.html">虚拟主机空间——“学以致用”计划</a>，现在有了不少的会员。本文主要是针对我们的会员遇到问题时参考来解决问题用的，如果您拥有自己的网站，使用的是其他的空间商提供的空间，如果有类似问题的读者也可以参考，希望对您有所帮助。</p>
<h3>先了解一些基本原理</h3>
<p>当您制作完成了一个网站，租用一个“学以致用”空间（或者称为虚拟主机），把网站发布到了空间，这时全世界的人都可以访问你的网站了。有的时候，会遇到一些问题，比如网站连不上了，或者觉得网页装载的速度不够快等等，当然遇到这种情况，可以给我们发信，我们会帮你检查。</p>
<p>但是在这里介绍一下，你应该做哪些自己可以做的检查工作，这也大致可以判断出问题出在哪里。这里先介绍一些简单的原理性知识.</p>
<p>我们知道，访问一个网站，输入一个网址，最终看到了你要看的网页，数据的传递实际上经过了千山万水，很多个环节，大致包括以下几个部分：</p>
<div style="border:1px solid #BBB">
<p>1：你自己的电脑。</p>
<p>2：如果你是在一个局域网，比如单位或家庭的局域网，则要经过局域网的路由器链接到互联网上。</p>
<p>3：互联网会从你家附近的电信局一个节点一个节点地找到目标服务器。</p>
<p>4：如果你的服务器在国外，还会经过海底光缆，进入其他大陆的互联网（我们给会员提供的服务器是位于美国的）。</p>
<p>5：进入服务器所在的机房（数据中心）。</p>
<p>6：到达最终的服务器，服务器根据请求的页面，产生网页内容，再沿着上述路径返回传输到你的电脑上。</p>
</div>
<p>因此，如果在这一些列的传输过程中，任何一个节点出现故障，都会导致无法看到你要看的网页。如果你的网站不能够正常打开了，首先要判断一下是在上述6个环节中的哪一个环节出了问题。</p>
<h3>自检步骤</h3>
<p>请根据下列操作进行分析：</p>
<p>1：首先如果可以正常上新浪、Google、百度等网站（注意确认打开的不是缓存网页，最好使用Google随便搜索一个词，看看返回的结果是否正常），说明你的电脑和外界的互联网连接正常，反之说明你的电脑或者内部的局域网连接有问题了。</p>
<p>2：如果可以访问新浪等大网站，而无法访问你自己的网站，那么就需要判断是哪里断了？可以用下面两种方法</p>
<p>      A: 比较快速的方法，使用 Ping 命令。选择Windows 的开始菜单，选择“所有程序 > 附件 > 命令提示符”，这时出现一个命令行窗口。用键盘输入&#8221;ping 你要诊断的网站的域名&#8221;，然后回车，这时，如果网络连接正常时，将会看到如下所示的结果。</p>
<p><img src='http://learning.artech.cn/wp-content/uploads/2009/11/ping-1.gif' alt='ping结果' /></p>
<p>而如果网络连接的某个环节发生中断时，将会看到如下所示的结果，说明无法连接到你要看的网页所在的服务器。</p>
<p><img src='http://learning.artech.cn/wp-content/uploads/2009/11/ping-2.gif' alt='ping结果' /></p>
<p>    B：同过上面的 Ping 命令，可以检查从你的电脑到目标服务器之间的网络连接是否通畅。此外，还有一个比Ping命令更为详细的命令 —— Tracert 。</p>
<p>        对于服务器在国外的情况，比如我们的虚拟主机，如果出现了中断，需要判断一下中断的路由器在国内还是国外。可以进入命令行窗口，然后使用“Tracert”命令。</p>
<p>       对于链接通畅的网站，结果应该是如下所示。</p>
<p>       <img src='http://learning.artech.cn/wp-content/uploads/2009/11/tracert-1.gif' alt='tracert-1.gif' /></p>
<p>       其结果显示的就是从你的电脑到目标服务器之间经过所有路由器的IP地址，注意每一行中间有一个几十或几百的数字，其确切含义这里不多解释了，只是你会注意到，从起点开始这个数值一般情况下会越来越大，特鄙视你会看到，其中有一跳之后数字突然从几十毫秒变成200多毫秒，这就是从国内的网络进入了国外的网络。</p>
<p>      如果某一个途中的某个路由发生故障，那么在从该节点开始，原来现实毫秒数的数值就会显示为星号，如图所示，表示连接发生故障了。</p>
<p>      <img src='http://learning.artech.cn/wp-content/uploads/2009/11/tracert-2.gif' alt='tracert-2.gif' /></p>
<p> 某一个节点发生了故障而导致中断，你就可以判断故障发生在国内还是国外。看一下上面正常的那个tracert结果图，数字很小的那些节点如果变成星号了，就说明是国内的网络出问题了，而如果时是后面数字比较大的节点变成星号了，就说明国外的某个网络节点出问题了。</p>
<p>从我这四五年的经验来看，这种骨干网发生故障的情况并不多见，尤其是国外一侧几乎一年于不到两三次，每次最多几分钟，国内相比之下就会多不少，特别是似乎几个月会调整路由，会在某一天或几天中，频频发生故障，而我们用户也没有什么办法，只能等待。</p>
<p>     因此，当你发现国内或者国外的路由节点发生故障了，就耐心等待一会儿，一般就会好了，因为这些骨干线路发生故障，影响面很大，会很快修好的。</p>
<p>3：如果使用Tracert命令发现整个路由的最后一个节点无法，也就是目标服务器显示的星号，那就说明是这台服务器当机（死机 、停机，总之是故障了），可以给我们发邮件，我们给你查一下。给我们发邮件的时候，请附一个路由结果。</p>
<p>4：如果服务器可以Ping通，即最后一节点也可以正常显示出正常的毫秒数值，但是网站打不开，那很可能是服务器还没有完全死机，但是一些服务，比如HTTP服务已经无法正常运行了，可以给我们发邮件，我们给你查一下。 给我们发邮件的时候，请附一个路由结果。</p>
<p>上述第3、4两点如果发生故障，那就是服务器提供商的责任了，就我们的经验看来，我们选用的服务商的服务还是相当稳定的。</p>
<p>上面说的是如果你的网站完全无法连接的时候，如何判断故障原因。接下来，有的时候，你会觉得打开速度不够快。这个问题就很复杂了。特别是中国的网络情况是非常复杂的，全国各地访问同一台服务器，结果速度可能就相差很多。</p>
<p>因此，建议你这样做：</p>
<p>1：平常没事儿的时候，也可以用tracert命令查一下从你的电脑到目标服务器之间的路由结果，这样平常有个印象，当某一个时刻，你感觉网站的速度不如平常的时候，tracert一下，看一看结果是否和平常相同，如果结果正常，那么或者是你的网站的设置出问题了，或者可能你是你的心理作用了，既不是网络的链接问题。</p>
<p>2：如果发现路由中，某个节点的数值突然变大了很多，那就说明是这个节点的路由器有点问题了，这个也做不了大多，一般来说经过一段时间，就会恢复正常了。</p>
<p>3：如果你没有发现任何问题，但是觉得速度很慢，可以这样检测一下：</p>
<p>首先，安装一个Firefox浏览器，然后安装Firefox的一个插件，叫做<strong>Firebug</strong>，利用这个插件，可以精确地测量一个页面的详细的装载过程和时间，例如</p>
<p><img src='http://learning.artech.cn/wp-content/uploads/2009/11/firebug-1.gif' alt='firebug' /></p>
<p>如图所示，安装好Firebug以后，可以在Firefox浏览器的右下角看到一个小虫子的图标，单击该图标，在浏览器窗口的下半部，会出现一个新的窗口，如图中的红色方框所示，选择“网络”、“所有”，然后浏览一个网页，这是下侧的窗口里就会显示出该页面中包括的所有文件，比如html文件、CSS文件、图像文件等等，完整的如下图所示。</p>
<p><img src='http://learning.artech.cn/wp-content/uploads/2009/11/firebug-2.gif' alt='firebug监视网页加载的时间' /></p>
<p>可以看到，列出了每个文件的大小，以及装载的次序，每个文件的后面有一个彩色的横柱图示，不同颜色代表装载该文件的不同阶段，其实就是对应于本文开头说的那些步骤。</p>
<p>你用这个插件查看一下你的网站的装载情况，看看主要慢在哪里，比如是否页面的体积太大？图排太多？图片没有压缩？如果你还是无法判断，把这个图发新给我们，我们给你看一下，是否正常，以及可能出现的问题。注意Firebug窗口的最底下计算了整个页面的所有文件的总的大小，以及完整装入浏览器的总时间，比如图中这个页面，所有文件加在一起200多K字节，一共用了5秒多装载，基本上可以接受。当然这里面要说的话，还有很多很多讲究的，并非几句话可以说清的了。</p>
<p>顺表说一句题外话，Firebug这个插件功能非常强大，对于网页设计，特别是要跟CSS打交道的设计师，以及要做Javascript开发的人员，Firebug都是必不可少的工具。以后有时间的时候，我会写一些相关的文章，介绍一下。</p>
<h3>本文总结</h3>
<p>如果遇到访问或者网络连接问题，请仔细阅读上文，如果仔细看过之后仍然无法找到原因，请给我们发邮件，在邮件中，请附带执行tracert命令的图，如果您的网站可以打开，但是觉得速度慢，在邮件初中附上Tracert的图，以及firebug的装载时间图，以便我们帮你查找原因。</p>
<p>如果你发现你的<a target="_blank" href="http://talking.artech.cn/thread-1003-1-1.html">“学以致用”</a>主机的网站无法访问，或者感觉速度不好，经过上述检查手段，仍然无法发现原因，请给我们发邮件。在邮件中请包括必要的内容：</p>
<p>1：一定要包括一个 Tracert 你的网站 的结果截图。</p>
<p>2：如果网也打得开，但是你觉得网站打开的速度慢，请包括一个firebug的页面装载时间图，就像上面第二个firebug图那样的图。</p>
<p>如果您使用的是其他虚拟主机，遇到类似问题，也可以把这些结果发给客户服务的技术支持人员。就像到医院看病一下，关键是要找出问题的原因在哪里，然后再能够解决。用一些工具去进行判断，就像看病的时候要做化验、做CT扫描等检查一样，都是很重要的手段。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20091104.server-network-checking.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>随笔随心(6) —— 闯荡北京值不值？</title>
		<link>http://learning.artech.cn/20091103.living-in-beijing.html</link>
		<comments>http://learning.artech.cn/20091103.living-in-beijing.html#comments</comments>
		<pubDate>Tue, 03 Nov 2009 11:55:17 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[随心随笔]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20091103.living-in-beijing.html</guid>
		<description><![CDATA[一位老朋友 keelii 今天问了一个问题：
老师最近忙不？闲的话我请教个问题：最近我们都已经在找工作了，学校也来了很多招聘的公司，但都没有软件方面的。我本身是学软件技术专业的，但... ]]></description>
			<content:encoded><![CDATA[<p>一位老朋友 keelii 今天问了一个问题：</p>
<p style="color:#B00;">老师最近忙不？闲的话我请教个问题：最近我们都已经在找工作了，学校也来了很多招聘的公司，但都没有软件方面的。我本身是学软件技术专业的，但对网页设计和前端工发比较感兴趣。想找一份前端的工作，初步打算去北京。老师能给点建议吧？先谢谢啦！</p>
<p>这里我说几点我的想法吧。我觉得凡事都是有利有弊的。</p>
<h3>这里先说北京的坏处吧：</h3>
<p>1：生活成本比较高，特别是房价太高，没有基础的年轻人，只身北京闯荡，开始的艰苦可想而知。而且成功的概率也并不是100%，不努力肯定不行，努力了也不一定就行。除非发展非常顺利，否则想挣出一套房子，都已经非常困难了。</p>
<p>2：气候不算好，冬天冷，过日子可能未必舒服。</p>
<p>3：城市太大，交通拥堵，上班费劲，总之在北京有很多不方便。</p>
<p>4：相比之下，北京的生活没有很多城市休闲。</p>
<h3>北京的好处：</h3>
<p>1：公司多，机会多。牛人多，便于你学习。如果善于处事，加之自身努力，过上世俗意思以上的好日子也是没问题的。</p>
<p>2：在北京，无论做什么行业，市场容量都极大，金字塔形的层次很多，无论你是什么水平，都可以找到一个适合你生存的层次。一条完整的食物链，无论是大鲨鱼，还是小虾米，都能活。如果努力勤奋又肯动脑子的话，北京是个很好的发展事业的地方。</p>
<p>3：北京可以算是一个移民城市了，真正祖上几代都是北京人的并不多，因此相对来说，外来的人在和本地人相处，相对比较容易一些。1949年解放的时候，北京只有200万人，现在快2000万了，多出来的都是移民。</p>
<p>4：北京经历的问题，其它城市将来都会经历，比如交通拥堵、环境污染等等，其它城市如果现在还没有遇到，只是因为还没有到时候而已。比如说交通，北京从2000年开始，汽车数量开始猛增，很多城市从今两三年开始汽车猛增，所以很多城市的交通问题很快就会爆发了。如果你在中国不同城市开过车，会发现北京的交通管理、交通设施算是非常好的，因为已经堵了这么多年了，久病成医嘛。在比如空气不好，但是我发现中国的各个大城市，没有哪个好的，而且北京的空气这几年特别是今年，比原来还真是好的多了。这是集权政府不多的一点优点了。</p>
<h3>结论</h3>
<p>从我身边看到的人来说，应该可以分为4类了:</p>
<p>1：不少没有任何基础的来到北京发展的非常好的；</p>
<p>2：也有干了多年发展很不得顺利离开的；</p>
<p>3：并不是工作的原因，而是因为其他原因，比如生活、家庭等原因，离开北京去其它城市的。</p>
<p>4：也有不好不坏的，也还在北京继续生活的；</p>
<p>不过总体来说，似乎留下来，并且过得越来越好的，还是占大多数。</p>
<p>所以关键还是要看自己的理想、基础、能力、性格等各个方面。 其实工作来说，未必只看着北京，我觉得比如成都这样的城市，也很不错，大学多，人力资源丰富，这就决定了一定会发展的很快，而且，相对物价低一些，吃得又好，生活舒适。就好像人们选股票，关键要找价值被低估的洼地，将来升值的空间就会更大。只是没有人能预测未来，所以只能看自己的感觉了。</p>
<p>总之，年轻的时候创一创还是值得的！但是还是要审时度势。既要低头拉车，也要抬头看路。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20091103.living-in-beijing.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>随笔随心(5) —— 沙漠里可以钓鱼吗？</title>
		<link>http://learning.artech.cn/20091029.mis-is-important.html</link>
		<comments>http://learning.artech.cn/20091029.mis-is-important.html#comments</comments>
		<pubDate>Thu, 29 Oct 2009 03:32:07 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[随心随笔]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20091029.%e9%9a%8f%e7%ac%94%e9%9a%8f%e5%bf%835-%e2%80%94%e2%80%94-%e6%b2%99%e6%bc%a0%e9%87%8c%e5%8f%af%e4%bb%a5%e9%92%93%e9%b1%bc%e5%90%97%ef%bc%9f.html</guid>
		<description><![CDATA[俺的太太和俺从事完全不同的工作，所以一般来说对工作上的事交流不多，不过最近几天，她跟我说了一些她们行业内的事情，我倒是觉得有点意思。
“马士基”（Maersk）是世界上最大的航运... ]]></description>
			<content:encoded><![CDATA[<p>俺的太太和俺从事完全不同的工作，所以一般来说对工作上的事交流不多，不过最近几天，她跟我说了一些她们行业内的事情，我倒是觉得有点意思。</p>
<p>“马士基”（Maersk）是世界上最大的航运物流公司，2008年的收入为 612.11 亿美元，在全球125个国家拥有6万多名员工，是一个巨无霸级别的公司。马士基进入中国已经多年，办公地点自然设在东部沿海的港口城市（青岛、上海、厦门、广州、深圳和香港），比如马士基中国总部在深圳，有员工1000多人，北方区的中心在青岛，也有数百人的规模。</p>
<p>但是09年，马士基做出了重大的变化，整个深圳总部的办公室完全撤销，青岛的办公室仅保留很少的人员，大部分与客户操作相关的职位全部撤销。那么这些工作的地点放到哪里去呢？答案请看这篇前几天的新闻——“<a target="_blank" href="http://scnews.newssc.org/system/2009/10/17/012377306.shtml">马士基全球最大office扎营成都 </a>”。</p>
<p>对于很多沿海港口城市，比如青岛，很大比例的人在各种大大小小的内外资公司里，从事和航运物流相关的工作，对于这些城市，这是得天独厚的先天优势，就像靠山吃山、靠水吃水一样，“靠海吃海”是天经地义的事。忽然间，地处内陆深处的成都人要来做这些工作了，这不是好像“在干旱的沙漠里钓鱼”吗？听起来真是有些不可思议。</p>
<h3>那么到底是什么导致了这样的变化呢？</h3>
<p>1：人们首先会想到的是人力成本的差异，东部沿海城市人力成本已经相当高了。相比之下，成都则有着相当大的优势 —— 大学众多意味着较高的人力资源水平，较低的物价水平。</p>
<p>2：但我个人感觉，最核心的因素是“网络和信息技术的成熟”。如果仅仅是因为降低一些员工的工资，还完全不是根本性的变化，因为比如青岛的人均工资水平并不是很高的，和成都并没有本质的区别。更何况，成都远离港口。真正的变化是由于网络和IT技术的成熟，如上面的新闻中说的：“马士基集团将在成都设立单证处理中心以及物流处理分公司，其中包括全球信息服务中心(Global Service Center)，用于<strong style="color:#C00;">处理来自全球的马士基后台业务流程</strong>。”这是什么意思呢？原来很多需要在港口边上处理的业务，现在并不需要在当地处理，甚至全球的业务都可以集中一个地方处理。这就是信息技术带来的真正变革。</p>
<p>实际上，在这里还是那里办公，还仅仅是一个方面，更为重要的是，通过新技术可以将很多原来需要人工处理的工作彻底自动化，而不需要人工操作了。比如，原来客户订舱位，需要有客户服务进行操作，现在全可以在网上进行，从而大大减少了客户服务的工作。除了对外的服务可以节约劳动力，通过使用内部信息系统，同样可以大幅度提高工作效率。这些系统都是一个公司真正的核心竞争力，而且是别人完全无法模仿的内在核心竞争力。</p>
<p>因此，网络就像一根长长的鱼竿，让成都人坐在几千公里外，照样可以钓到海里的大鱼，甚至大西洋、印度洋里的鱼了。</p>
<p>3：完善的培训机制。我原来对于马士基把大量工作岗位从沿海城市搬到成都，有一个疑问，一下子能招聘到那么多有经验的员工吗？成都毕竟不像青岛、深圳这样，多年来已经积累了大量的相关行业人员。太太告诉我，马士基这样的公司有着很好的培训机制，他们可以大量招聘大学应届毕业生，一张白纸不要紧，招进来以后，再培训，也来得及。而这种完善的配机制，也同样大大依赖于网络和信息技术的发展。</p>
<h3>能够给我们什么启示</h3>
<p>一个公司，对信息技术的使用，是核心竞争力的重要一环。相比之下，国内的很企业，与先进的企业还是有非常大的差距的，这个差距其实是有历史原因的。一个企业开发和部署信息系统，和我们一般人使用电脑完全不同，微软发布了Windows 7，我们只要装上它就能用了，你和比尔盖茨使用的是一样的Windows。但是对于一个企业，要部署一套和业务流程匹配的信息系统，就完全不是“装上就能用”这么简单的事儿了。</p>
<p>比如，欧美发达国家的很多企业，早在还没有电子计算机的年代，信息系统就已经开始大规模的应用了。比如说，我多年前看过一本书叫做《父与子——IBM发家史》，这个书名翻译的很没档次，但是书的内容很好，作者是IBM第二代掌门，一个曾经是花花公子，后来成功带领IBM高速发展的美国“富二代”（和当今中国的“富二代”不同的是，他玩的是飞机而不是跑车。希望中国的“富二代”在过了荷尔蒙和多巴胺控制的青春期以后，也可以做点有益的事情）。从书中可以看到，IBM在生产计算机之前，他们的主要产品是打孔机，实质上就是一种机械式的记录信息的机器，只是使用在纸板上打孔的方式来记录信息，他在书中描述，那时他们的客户为了保存这些纸卡，就要用几层楼的空间。从中我们可以得出什么结论呢？在几十年前，没有现代的计算机、也没有互联网的时代，人家就已经通过现在看来很原始的方式在构建信息管理系统，从根本意义上说，在纸上打孔，还是保存在磁盘上，仅仅是方式的不同，而没有本质的区别。而那个时代，中国正是失去的30年。因此，现在，虽然我们也可以买到和美国人一样的电脑的时候，其实对于信息管理的认识和实践，已经相差了几十年。</p>
<h3>本文小结</h3>
<p>上次翻译了一篇文章叫做《<a target="_blank" href="http://learning.artech.cn/20090616.freelancer-trends.html">大多数设计师将成为自由职业者</a>》，说的是网络和信息技术对普通的个体的影响，今天说的就是对企业的影响了。</p>
<p>我们的读者中，有很多还是学生朋友，我这篇文章，实在告诉你，软件开发绝对是一个朝阳行业，特别是在中国，还有极大的空间，将来可做的事情太多太多。</p>
<p>如果你是一个从事软件相关工作的人，特别是从事和客户直接相关的项目开发，我觉得一定要充分理解客户的需要，只有对客户真正有实效的信息系统，才能真正产生价值。只有这样，你的工作才能产生更大的效益。据说中国企业实施信息系统的成功率只有30%，如果你做的项目属于不成功的70%，就算挣到了这个项目的钱，损失还是很多的。因此，在选择客户的时候，也要看一看这个客户，特别是客户的领导，是不是真的希望使用这个系统，要用这个系统产生实效，这样的客户才是好客户。</p>
<p>如果你是一个企业中的管理人员，你有没有花一些时间考虑一下，你公司、部门的工作中是否还存在可以挖掘的潜力，通过利用信息化的手段，提供工作效率，降低成本呢？</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20091029.mis-is-important.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Web开发杂谈(8) —— 一个很基础的问题（表达式求值顺序）</title>
		<link>http://learning.artech.cn/20091022.expression-evaluation.html</link>
		<comments>http://learning.artech.cn/20091022.expression-evaluation.html#comments</comments>
		<pubDate>Thu, 22 Oct 2009 08:02:50 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[Web开发杂谈]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20091022.expression-evaluation.html</guid>
		<description><![CDATA[前几天一位读者在这里留言问了一个程序设计中很基础，其实也很经典、而且历史悠久的问题，我简单回答了一下，后来发现还有不少读者对此有兴趣，因此就展开来说一说吧。
他的问题是这... ]]></description>
			<content:encoded><![CDATA[<p>前几天一位读者在这里留言问了一个程序设计中很基础，其实也很经典、而且历史悠久的问题，我简单回答了一下，后来发现还有不少读者对此有兴趣，因此就展开来说一说吧。</p>
<p>他的问题是这样的，对于下面这段的代码，执行完成后，变量m的值应该是是多少？</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="c">main<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#123;</span>
    <span style="color: #993333;">int</span> i=<span style="color: #cc66cc;">2</span>,m=<span style="color: #cc66cc;">2</span> ;
    m+=<span style="color: #66cc66;">&#40;</span>i++<span style="color: #66cc66;">&#41;</span> + <span style="color: #66cc66;">&#40;</span>++i<span style="color: #66cc66;">&#41;</span> + <span style="color: #66cc66;">&#40;</span>i++<span style="color: #66cc66;">&#41;</span> ;
   <span style="color: #000066;">printf</span><span style="color: #66cc66;">&#40;</span> <span style="color: #ff0000;">&quot;%d&quot;</span> , m<span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>这位读者在TC（我猜想用的是Turbo C 2.0 ？）中得到的结果是 11 。<a target = "_blank" href="http://learning.artech.cn/guest-book-5#comment-11052">具体读者讨论可以看这里</a>。</p>
<p>当时我给出了一个很简略地回答：</p>
<div style="border:1px solid #BBB;">
<p>这个问题其实挺复杂的，这个表达式在不同的语言中的结果是不一样的，比如在 C、C#、Perl、Java中的结果是不一样的，每种语言对这个求值得逻辑有各自不同的定义。</p>
<p>所以最好不要写这样的表达式。也没有必要，要计算什么就要最明确的方式写出来。</p>
</div>
<p>不过后来有几位读者仍然围绕着为什么等于11讨论了几个帖子，这几位读者似乎并没有注意俺当时的回复。在上面简单回答中，并没有非常深入，只提到了不同语言对此有不同，其实即使同一种语言，也有更为复杂的情况。因此这里就展开谈一谈。</p>
<h3>问题化简</h3>
<p>实际上，这种类似的题目在20年前的C语言教科书或者考试经常出现，但是现在如果再出这种题目，那么要么是对学生是很不负责任的老师，要么是非常负责任的老师。</p>
<p>我们先不管上面问题中的代码，而是先看一个更简单的表达式求值问题：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="c">    <span style="color: #993333;">int</span> x=<span style="color: #cc66cc;">1</span>;
    x = x++;</pre></td></tr></table></div>

<p>请读者考虑一下，对于C（C++）语言，上面代码执行完成后，x的值应该是多少？</p>
<p>思路一： 先计算表达式 x++ ，此时其值为1，然后将 x++的值将其赋给x，因此x的值等于1。</p>
<p>思路二：先计算表达式 x++ ，此时其值为1，然后将其赋给x，此时x的值等于1，然后执行x加1的运算，因此最终x的值等于2。</p>
<p>那么上面两种思路，哪个是正确的呢？</p>
<p>正确的答案是，都不对，而正确的回答是：“这个值是不确定的”。</p>
<h3>&#8220;语言&#8221;与&#8221;实现&#8221;</h3>
<p>首先要了解一个“语言”（比如C语言、C++语言），和一个语言的“实现”（比如Turbo C 2.0 和 Visual C++ 6.0）之间的区别。这个类似于“CSS规范”与“浏览器”之间的关系，尽管CSS的标准是统一的，但是各个浏览器厂商有各自对CSS的实现方式，并且存在着差异。</p>
<p>同样，一个语言仅仅是一个规范，它规定了一个语言的语义，而各个编译器厂商对一个语言有各自的实现。和浏览器实现CSS之间的差异不同，在这里，并不是由于各编译器厂商对语言本身的理解不同导致的差异，而是在规范中就给出了明确的自由空间给编译器厂商。例如在linux下用gcc编译出来的程序和用turbo C编译出来的程序， 得到的结果就会不同。</p>
<p>下面具体看一下规范是如何定义的。</p>
<h4>A：表达式的值与副作用</h4>
<p><strong>表达式</strong>有两种功能。每个表达式都产生一个<strong>值</strong>( value )，同时可能包含<strong>副作用</strong>( side effect )。副作用是指改变了某些变量的值。</p>
<p>比如：</p>
<p>1： 20    //这个表达式的值是20；它没有副作用，因为即它没有改变任何变量的值。</p>
<p>2： x=5  // 这个表达式的值是5；它有一个副作用，因为它改变了变量x的值。</p>
<p>3： x=y++ // 这个表示有两个副作用，因为改变了两个变量的值。</p>
<p>4： x=x++ // 这个表单时也有两个副作用，因为变量x的值发生了两次改变。</p>
<h4>B：求值顺序点</h4>
<p>表达式求值规则的核心在于<strong> 顺序点</strong>( sequence point ) [ C99 6.5 Expressions 条款2 ] [ C++03 5 Expressions 概述 条款4 ]。 </p>
<p>顺序点的意思是在一系列步骤中的一个“结算”的点，语言要求这一时刻的求值和副作用全部完成，才能进入下面的部分。 C/C++中大部分表达式都没有顺序点，只有下面五种表达式有：</p>
<p>    1： 函数。函数调用之前有一个求值顺序点。</p>
<p>    2 ：&#038;&#038;  || 和 ?:  这三个包含逻辑的表达式。其左侧逻辑完成后有一个求值顺序点。</p>
<p>    3 ：逗号表达式。逗号左侧有一个求值顺序点。</p>
<p>    注意，他们都只有一个求值顺序点，2和3的右侧运算结束后并没有求值顺序点。</p>
<h4>C:  最重要的一点</h4>
<p>C1：对于C和C++语言：</p>
<p>在两个顺序点之间，子表达式求值和副作用的顺序是不同步的。如果代码的结果与求值和副作用发生顺序相关，称这样的代码有不确定的行为(unspecified behavior)。 而且，假如期间对一个内建类型执行一次以上的写操作，则是未定义行为(undefined behavior)。</p>
<p>举例来说，对于表达式  x=x++ ，副作用发生的顺序，也就是赋值和自增1运算在何时执行，C/C++语言本身没有规定，而将其交给编译器厂商来自行决定。</p>
<p>C2：对于C#和Java语言，对于表达式的求值顺序和副作用发生顺序都有严格的定义，这样任何符合C#（或者Java）规范的编译器，对于相同的表达，求出来的值都是相同的。</p>
<h4>D：为什么要这么做呢？</h4>
<p>对于C/C++语言：</p>
<p>因为对于编译器提供商来说，未确定的顺序对优化有相当重要的作用。编译器可以重新组织表达式的求值，以便尽量不使用额外的寄存器以及临时变量。更加严格的说，即使是编译器提供商也无法完全彻底序列化指令（比如无法严格规定读和写的顺序），因为CPU本身有权利修改指令顺序，以便达到更高的速度。</p>
<p>对于C#和Java语言：</p>
<p>在规范中严格定义副作用的发生顺需，可以保证相同的代码产生相同的结果，这样对于程序的维护、升级都会方便得多。</p>
<h4>E：重要结论</h4>
<p>在写程序的时候，不要写依赖于“实现”的代码。因为代码在未来有可能要移植、要升级，也就是相同的源代码可能会到不同的“实现”中进行编译，从而带来潜在的问题，有可能这些问题在未来某个未知的时间才会发作，到那个时候，再想找到某个深藏着的问题，就会非常困难了。</p>
<h3>再回到我们的例子中</h3>
<p>对于这段简单的代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="c">    <span style="color: #993333;">int</span> i=<span style="color: #cc66cc;">1</span>;
    i = i++;</pre></td></tr></table></div>

<p>这里仅给出来Visual studi 2008中，的C++语言 和 C#语言中的不同表现，并进行一些说明。</p>
<p>如果使用 C++，运算完成后， i 的值等于2；而如果使用C#，运算完成后，i的值等于1。</p>
<p>这里可以分别看一下，在C++和C#中，上面这两行代码分别对应的汇编代码，就可以非常清楚了。在Visual Studio中可以很方便地查看语句对应的汇编代码。</p>
<p>在C++中得到的汇编代码是：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="asm">         // i =  i++ <span style="color: #adadad; font-style: italic;">;</span>
         <span style="color: #00007f;">nop</span>              
         <span style="color: #00007f;">inc</span>  <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp<span style="color: #ff0000;">-4</span><span style="color: #66cc66;">&#93;</span></pre></td></tr></table></div>

<p>ebp-4 就是变量i的地址， [ebp-4] 表示的就是变量i的值很简单，可以看到，这里的处理方式是直接把变量i的值加1。</p>
<p>而在C#中得到的汇编代码是：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="asm">          // i =  i++<span style="color: #adadad; font-style: italic;">;</span>
         <span style="color: #00007f;">mov</span>         <span style="color: #46aa03; font-weight:bold;">eax</span>,<span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-3Ch<span style="color: #66cc66;">&#93;</span> 
         <span style="color: #00007f;">mov</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-40h<span style="color: #66cc66;">&#93;</span>,<span style="color: #46aa03; font-weight:bold;">eax</span> 
         <span style="color: #00007f;">inc</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-3Ch<span style="color: #66cc66;">&#93;</span> 
         <span style="color: #00007f;">mov</span>         <span style="color: #46aa03; font-weight:bold;">eax</span>,<span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-40h<span style="color: #66cc66;">&#93;</span> 
         <span style="color: #00007f;">mov</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-3Ch<span style="color: #66cc66;">&#93;</span>,<span style="color: #46aa03; font-weight:bold;">eax</span></pre></td></tr></table></div>

<p>ebp-3Ch 就是变量i的地址， [ebp-3Ch] 表示的就是变量i的值，上述代码的执行过程是：</p>
<p style="text-indent:0px;">
1：首先把变量i的值复制到寄存器EAX中，<br />
2：把寄存器EAX中值复制到一个临时地址中，<br />
3：把变量i的值加1，<br />
4：把第2步中的临时变量的值复制回EAX中，<br />
5：把EAX中的值复制回变量i中。
</p>
<p>由此可见，自增运算的实际上并没有产生实际的作用。</p>
<p>现在再看一下最开始的问题，m+=(i++) + (++i) + (i++) 是如何等于11的呢？还是来看一下汇编代码，这是最准确的答案了。在Visual Studio中，这个语句对应的汇编代码是：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="asm">          //m+=<span style="color: #66cc66;">&#40;</span>i++<span style="color: #66cc66;">&#41;</span>+<span style="color: #66cc66;">&#40;</span>++i<span style="color: #66cc66;">&#41;</span>+<span style="color: #66cc66;">&#40;</span>i++<span style="color: #66cc66;">&#41;</span><span style="color: #adadad; font-style: italic;">;</span>
           <span style="color: #00007f;">inc</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp<span style="color: #ff0000;">-4</span><span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">mov</span>         <span style="color: #46aa03; font-weight:bold;">eax</span>,<span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp<span style="color: #ff0000;">-8</span><span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">add</span>         <span style="color: #46aa03; font-weight:bold;">eax</span>,<span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp<span style="color: #ff0000;">-4</span><span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">add</span>         <span style="color: #46aa03; font-weight:bold;">eax</span>,<span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp<span style="color: #ff0000;">-4</span><span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">add</span>         <span style="color: #46aa03; font-weight:bold;">eax</span>,<span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp<span style="color: #ff0000;">-4</span><span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">mov</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp<span style="color: #ff0000;">-8</span><span style="color: #66cc66;">&#93;</span>,<span style="color: #46aa03; font-weight:bold;">eax</span> 
           <span style="color: #00007f;">inc</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp<span style="color: #ff0000;">-4</span><span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">inc</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp<span style="color: #ff0000;">-4</span><span style="color: #66cc66;">&#93;</span></pre></td></tr></table></div>

<p>从上面的汇编代码，就很清楚11如何计算出来的了，首先把变量i的值加了1，这时i就等于3了，然后累加了3次，即 m = 2+3+3+3 ，从而 m = 11 。上面汇编代码中最后两行又把i两次加1，但是和m的值已经无关了。</p>
<p>因此，用清晰的写法，m+=(i++) + (++i) + (i++) 在C++中等价于：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="c">        <span style="color: #808080; font-style: italic;">//int i=2；</span>
        <span style="color: #808080; font-style: italic;">//int m=2；</span>
&nbsp;
        i=i<span style="color: #cc66cc;">+1</span>;             <span style="color: #808080; font-style: italic;">// m=2, i=3</span>
        m=m+i+i+i;   <span style="color: #808080; font-style: italic;">// m=11,i=3</span>
        i=i<span style="color: #cc66cc;">+1</span>;            <span style="color: #808080; font-style: italic;">// m=11,i=4</span>
        i=i<span style="color: #cc66cc;">+1</span>;            <span style="color: #808080; font-style: italic;">// m=11,i=5</span></pre></td></tr></table></div>

<p>那么再看看在C#语言中，同样的语句，产生的汇编代码又是如何的呢？</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="asm">           // m += <span style="color: #66cc66;">&#40;</span>i++<span style="color: #66cc66;">&#41;</span> + <span style="color: #66cc66;">&#40;</span>++i<span style="color: #66cc66;">&#41;</span> + <span style="color: #66cc66;">&#40;</span>i++<span style="color: #66cc66;">&#41;</span><span style="color: #adadad; font-style: italic;">;</span>
           <span style="color: #00007f;">mov</span>         <span style="color: #46aa03; font-weight:bold;">eax</span>,<span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-3Ch<span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">mov</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-44h<span style="color: #66cc66;">&#93;</span>,<span style="color: #46aa03; font-weight:bold;">eax</span> 
           <span style="color: #00007f;">inc</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-3Ch<span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">inc</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-3Ch<span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">mov</span>         <span style="color: #46aa03; font-weight:bold;">eax</span>,<span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-44h<span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">add</span>         <span style="color: #46aa03; font-weight:bold;">eax</span>,<span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-3Ch<span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">mov</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-48h<span style="color: #66cc66;">&#93;</span>,<span style="color: #46aa03; font-weight:bold;">eax</span> 
           <span style="color: #00007f;">mov</span>         <span style="color: #46aa03; font-weight:bold;">eax</span>,<span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-3Ch<span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">mov</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-4Ch<span style="color: #66cc66;">&#93;</span>,<span style="color: #46aa03; font-weight:bold;">eax</span> 
           <span style="color: #00007f;">inc</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-3Ch<span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">mov</span>         <span style="color: #46aa03; font-weight:bold;">eax</span>,<span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-40h<span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">add</span>         <span style="color: #46aa03; font-weight:bold;">eax</span>,<span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-48h<span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">add</span>         <span style="color: #46aa03; font-weight:bold;">eax</span>,<span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-4Ch<span style="color: #66cc66;">&#93;</span> 
           <span style="color: #00007f;">mov</span>         <span style="color: #0000ff;">dword</span> <span style="color: #0000ff;">ptr</span> <span style="color: #66cc66;">&#91;</span>ebp-40h<span style="color: #66cc66;">&#93;</span>,<span style="color: #46aa03; font-weight:bold;">eax</span></pre></td></tr></table></div>

<p>通过上面的汇编代码，可以看到在C#中，m+=(i++) + (++i) + (i++) 这个表达式等价于下面的程序段：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="c">        <span style="color: #808080; font-style: italic;">//int i=2；</span>
        <span style="color: #808080; font-style: italic;">//int m=2；</span>
&nbsp;
        <span style="color: #993333;">int</span> t1=i;           <span style="color: #808080; font-style: italic;">// m=2, i=2, t1=2</span>
        i= i<span style="color: #cc66cc;">+1</span>;             <span style="color: #808080; font-style: italic;">// m=2, i=3, t1=2</span>
        i= i<span style="color: #cc66cc;">+1</span>;             <span style="color: #808080; font-style: italic;">// m=2, i=4, t1=2</span>
        <span style="color: #993333;">int</span> t2= t1 + i  <span style="color: #808080; font-style: italic;">// m=2, i=4, t1=2,t2=6</span>
        <span style="color: #993333;">int</span> t3= i          <span style="color: #808080; font-style: italic;">//  m=2, i=4, t1=2,t2=6,t3=4</span>
        i= i<span style="color: #cc66cc;">+1</span>            <span style="color: #808080; font-style: italic;">//  m=2, i=5, t1=2,t2=6,t3=4</span>
        m=m+t2       <span style="color: #808080; font-style: italic;">// m=8, i=5, t1=2,t2=6,t3=4</span>
        m=m+t3       <span style="color: #808080; font-style: italic;">//m=12, i=5, t1=2,t2=6,t3=4</span></pre></td></tr></table></div>

<p>可以看到，里面使用了3个临时变量（即内存单元），而且步骤也比在C++中复杂。但是可以看到，在C#中，++运算符的副作用发生时间与求值过程是同步的，更接近与本来的语义。相比在C++中，二者就不是同步的了。</p>
<h3>面试指南</h3>
<p>前面已经强调，这样写代码是很不好的风格，建议不要写出这样的代码。但是如果你要是参加面试，或者其他考试碰到了这种题目应该怎么做呢？其实很简单。首先确定，如果用的是什么语言：</p>
<p>如果是C#或者Java，那么这就按照求值顺序，同步地对++ （- -）运算符计算相应的副作用发生顺序就可以了。前置或者后置的加减1，都是紧挨着求值进行的，参考上面从汇编代码翻译出来的C#代码。</p>
<p>如果是C/C++语言，就要问一下，使用什么编译器，使用Turbo C，还是VC，还是gcc，这样会显得你很专业，当然我并不知道所有编译器的表现，现在我知道是，Turbo C和VC9（visual Studio 2008，我猜测其他版本的VC应该大致相同，我没有验证过）中，这个求值顺序是这样的：</p>
<p>在开始计算之前，先把所有前置 ++ （- -）运算都计算完成（不考虑位置），比如上面的例子中，只有一个前置 ++，因此先把 i 加1，然后就开始计算表达式的值，而不再计算增减运算，直到下一个顺序点之前，把剩下的后置 ++ （- -）运算统一处理完，比如上面里中，有两个后置++，所以在最后赋值之前，把i变成5。</p>
<p>对其他编译器有兴趣的读者可以自己试试看，效果如何。</p>
<h3>不仅如此</h3>
<p>通过上面的讲解，似乎我们已经理解了表达式求值的过程，而实际上还有更为有趣的内容在等着你。</p>
<p>对于 m+=(i++) + (++i) + (i++) 这个表达式，在各种语言，比如C、C++、C#里面都是可以通过编译检查，并且能够计算出一个结果的，比如上面的例子，在C++和C#中分别等于11和12，但是实际上，这个写法是错误的——严格地说，是不符合标准的。也就是说，如果按照C/C++语言的标准，这个表达式的写法是错误的。</p>
<p>其原因是，在标准中要求，任何表达式在两个顺序点之间的求值过程中，任何一个变量的值只能修改一次。而m+=(i++) + (++i) + (i++) 这个表达式中，变量 i 被修改了3次，因此这个语句本身就是错误的。</p>
<p>因此，上面给出的简单的例子 x=x++ ，同样是一个错误的写法，因为x被修改了两次。</p>
<p>实际上，在任何一个语言的规范中，相关的内容还有非常非常多，当然对于一般的开发人员，不是打算自己写一个语言的编译器的话，不需要搞得太清楚，知道大致的原理就可以了。实际上，世界上真正写编译器的人并不多，比如在微软，参加编写 .net 框架的程序员有上千人（2002年的数字），而真正设计和编写C#编译器的人不超过5、6个人而已。</p>
<h3>总结</h3>
<p>1：可以看到，在表达式求值的过程中，具体副作用是什么时候发生的，这一点在不同语言，甚至同一种语言的不同的编译器上，结果都有可能不同。概括来说，就是求值的步骤，和修改变量的步骤并非同步的，由此会导致不同的结果。</p>
<p>因此，在写程序的时候，要尽量避免这种情况发生，写出语义清晰明确的代码，以避免由此带来的不确定性。</p>
<p>2：搞清楚一个问题真正的原因才能真正解决问题，关于表达式求值的问题，实际上是有着非常多问题可以深入的，例如上面提到了“不确定”这个结果，实际上严格来说，还有更为复杂和严谨的内容值得探讨，本文就不再细谈了。</p>
<p>建议有兴趣的读者参考下面两篇文章，上面文章中有部分文字来自于这篇文章：<a target="_blank" href="http://blog.csdn.net/ox_thedarkness/archive/2006/03/01/613122.aspx">关于C/C++ 表达式求值顺序</a> ， <a target="_blank" href="http://blog.csdn.net/pongba/archive/2005/12/01/541440.aspx">C++中的求值|副作用|序列点所导致的模糊语义</a> 。</p>
<p>3：掌握一些底层的基础知识，比如了解一些简单的汇编语言知识，在需要的时候，就可以用来解决一些问题，因此作为开发人员还是要深入掌握基础才好。</p>
<p>4：如果对某个语言有兴趣的，希望真正掌握好它，可以仔细读一读这个语言的标准，或者说规范，这对于很多概念的理解是非常有帮助的。例如对于C#的规范，安装了Visual Studio之后，在安装的文件夹 Microsoft Visual Studio 9.0\VC#\Specifications\1033 中有一个500多页的Word文档， 标题叫做《C# Language Specification (Version 3.0)》，很多很多你不理解的问题都可以在里面找到答案。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20091022.expression-evaluation.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>老书新荐——《圈子圈套》</title>
		<link>http://learning.artech.cn/20091010.quanziquantao.html</link>
		<comments>http://learning.artech.cn/20091010.quanziquantao.html#comments</comments>
		<pubDate>Sat, 10 Oct 2009 04:11:54 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[书评与推荐]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20091010.quanziquantao.html</guid>
		<description><![CDATA[《圈子圈套》早已经是一部非常热销的小说了，而且已经三、四年的时间了，只是我才刚刚在这个“十一”休息的时间看了一遍。感觉相当不错，内容虽然和技术没有太大无关，但是很有教益... ]]></description>
			<content:encoded><![CDATA[<p>《圈子圈套》早已经是一部非常热销的小说了，而且已经三、四年的时间了，只是我才刚刚在这个“十一”休息的时间看了一遍。感觉相当不错，内容虽然和技术没有太大无关，但是很有教益，因此也推荐给没有看过的朋友。</p>
<p><a target="_blank" href="http://www.amazon.cn/s?pageletid=headsearch&#038;searchType=&#038;i=aps&#038;keywords=圈子圈套&#038;Go.x=0&#038;Go.y=0&#038;source=artech&#038;searchKind=keyword">点击这里在亚马逊书店查看此书，最上面3本即是。</a></p>
<p>为什么我很早就听说过这本书，却一直根本不想看呢？是因为这部书的名字。我知道这本书是关于职场商战的书，但是这个名字让我以为这又是一本通行的“阴谋管理论”的书，因此并不感兴趣。现在市面上有很多书很流行，比如从前若干年的《水煮三国》，以及“中国式管理”等类似的书，看起来也热热闹闹，其实本质上是告诉你要通过阴谋诡计来获得胜利，这是我很反感的论点。在当今的中国，最不缺的就是阴谋诡计、尔虞我诈，最缺的正是鲁迅反对的“费厄泼赖”，我们的生活中处处充满陷阱，从手机短信到取款机，稍不留神，就给你上一课。以至于很多人把这些都归为中国人的“人性”，从而变成了理所当然的，这实在是很悲哀的事。 因此见到“圈子”、“圈套”这类词汇，即使我想作者出于让读者长经验的目的，我也并不想看。这就象，尽管我非常痛恨日本，但我不想去看关于南京大屠杀相关的电影，看了会让心情非常郁闷。</p>
<p>只是最近每天早上在广播里有这部书的小说连播，开车时听了一些，越来越觉得有意思，就索性把3集书都买了，果然是相当过瘾。这本书好就好在，他的态度非常积极，这是我欣赏的。此外还给出一些解决问题的方法，这也很好。书里附带了一张光盘，有一些作者讲演和问答的录像，其中有一个问题我觉得他的回答非常好。</p>
<p>这个问题就是关于销售中的行贿问题，这个问题是每一个在中国需要直接面对客户的人，都无法绕开的问题。要不要行贿？这是一个最基础的问题，恰恰昨天晚上电视上有一个节目，采访万科的老总王石，节目名字正好叫做“不行贿”，王石侃侃而谈了很多，核心的一句话是“我从不行贿、我的公司也从不行贿、即使生意做不成，也不行贿”，当然这是很好的做法，但是他并没有真正回答这个问题——在所有人都行贿的时候，你不行贿，怎么做生意呢？绝大多数人是没有王石的本事的，如果生意都不做了，岂不是要饿死？所以如果王石确实如他所说的从不行贿，那么他应该告诉观众，如果竞争对手都行贿，而你不行贿，有什么方法来赢得订单呢？</p>
<p>而《圈子圈套》作者王强的答案显然就实在的多，也更具有启发意义——“挖掘客户身上更高层次的需求”。这个答案是我以前没有想到的。解释一下，大致是这个意思：任何人的需求都是有层次的，比如吃饭、短期的金钱回报（回扣），但是同时他也会有更高层次的需求。如果作为一个销售，只能看到客户身上最底层的需求，一点点回扣、请客吃饭等等，那么你能给客户的，别人也能给。而你更应该看到客户的更高层次的需求。比如在圈子圈套第一部的“普发”这个项目中，主人公洪钧（或多或少是作者写他自己）在客户“普发集团”找到了一个同盟军——普发集团的总经理助理韩湘，洪钧发现了他的更高层次的需求，那就是韩湘非常需要一个可以实际地体现工作业绩的根据地，而这个企业信息化的项目，恰恰可以给他这样一个根据地，从而在整个项目从竞标到中标以后的全过程，韩湘都给了洪钧极大的帮助。当然，这个项目也给了韩湘极大的回报，这个回报在第三部中揭晓——他高升了。这就是一个重要的答案：回扣重要还是一个人的职业生涯、政治生命更重要呢？</p>
<p>再谈到“行贿”，其实也远非简单的“是”或“否”这样黑白分明的，就像在《圈子圈套》中，洪钧还是在项目中标以后，请韩湘到美国考察了一圈，并且在赌城给了他1000美元的筹码，这里不去讨论折合的金钱有多少，至少这在我看来还是很合理的，并不算有违道德，毕竟大家合作了，而人家又给了这么大的帮助，感谢一下也完全不算过分的。如果不表示一下，倒是说不过去了。但是韩湘愿意帮助洪钧，一定不是为了这这点钱。实际上，在书中，洪钧也多次运用那个了这个工具，而并非简单的“我绝不行贿”这么简单的一句话可以说清的。</p>
<p>这本书毕竟是一本小说，因此是否“好看”就很重要了，我觉得这本小说，确实很“好看”。不得不佩服作者的文笔、对细节的观察和把握，确实太棒了。形形色色的人物，描写的确实很“像”，这又回到了对细节的刻画上，确实很有趣。</p>
<p>从整体来说，第一集侧重于战术，第二集侧重于办公室政治，第三集侧重于战略与布局，都很精彩，值得一看。</p>
<p>下面说说一点遗憾，不是关于书本身的，而是关于书的后续的，我发现这么好的书，又很畅销，而现在竟然在网上找不到任何官方的网站、包括博客等内容了。这不能说是一点遗憾，想想看哈利波特的运作，哈利波特第一次印刷只有500册，谁也不知道它会火起来，而几年之后，哈利波特已经销售了4亿册，从500册到4亿册，还加上了电影、衍生产品，产生了超过200亿美元的市场（要知道，整个中国图书出版行业一年的总产值不过100亿美元而已）。而《圈子圈套》这么好的书，3年之后，竟然连官方网站都没有一个，实在是很可惜了。在网上了解到，根据《圈子圈套》改编了一部电视剧，叫做《魔方》，看了一些介绍和评论，相当不好，不知道这是作者的疏忽还是其他原因，实在是可惜，观众不满意电视剧的改编，弱化了职场的内容，而加入了很多感情的成分，而这部书之所以火起来，恰恰因为它不是一个感情小说，更为可笑的是，电视剧的结尾竟然是为了感情放弃了项目，这实在是令人匪夷所思。根据介绍，电视剧拍摄的结束和《圈子圈套》第3部的结束时同一个时间，也就是说电视剧的结尾是编剧给出的，而小说作者有自己的结尾，在我看来小说的第三部的结果相当好。如果这部电视和作者有关系的话，那么不得不说这是一个遗憾了，对比一下哈利波特的作者，罗琳，他在卖出电影版权的时候，保留了极大的权利，甚至否决了斯皮尔伯格来做导演，只因为她要保证他的想法得以贯彻。不能不说，作为一个商业社会，中国海还差的很远啊。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20091010.quanziquantao.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Web开发杂谈(7) ——软件开发与数学基础</title>
		<link>http://learning.artech.cn/20090811.web-dev-maths-basic.html</link>
		<comments>http://learning.artech.cn/20090811.web-dev-maths-basic.html#comments</comments>
		<pubDate>Tue, 11 Aug 2009 02:59:04 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[Web开发杂谈]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090811.web-dev-maths-basic.html</guid>
		<description><![CDATA[在上一篇文章《Web开发的入门建议》中，我稍微提了一下关于数学的问题，提到数学是很多计算机课程的基础，有几位网友也讨论了这个问题。我就由此想到了一些话题，今天随便聊聊。先来... ]]></description>
			<content:encoded><![CDATA[<p>在上一篇文章《<a target="_blank" href="http://learning.artech.cn/20090803.web-dev-abc.html">Web开发的入门建议</a>》中，我稍微提了一下关于数学的问题，提到数学是很多计算机课程的基础，有几位网友也讨论了这个问题。我就由此想到了一些话题，今天随便聊聊。先来举一个例子吧。</p>
<h3>一个C#中的例子——lambda表达式</h3>
<p>我们多次提到，当前来说，Web开发领域，开发工具（或者叫平台）的“三巨头”是 .Net、JAVA和PHP。如果用.Net，那么一般用C#语言(或者VB)，在C#语言3.0版中，引入了一个非常重要的新特性称为“lambda表达式”。首先来普及一下“lambda表达式”的概念和作用。lambda 是一个希腊字母“λ”的英文读音，我们中国人一般念作“拉姆达”。</p>
<p>首先，在C#中，可以用 lambda表达式来定义一个匿名的函数。例如 </p>
<p>x => x%2==0 </p>
<p>就定义了一个匿名的函数，这个函数的作用是判断一个参数是不是偶数。其中 &#8220;=>&#8221; 是C#中用用于定义lambda表达式的运算符，他前面的x是函数的输入参数，他后面是返回的结果，当x是偶数，即x除以2的余数等于0时返回true，否则返回false。那么定义了这么一个lambda表达式有什么用呢？还是看一个例子。</p>
<p>比如说，有一个一维数组，保存着若干整数，现在需要计算出其中大于0的个数。那么按照传统方法可以这么写：</p>
<p>int c=0;<br />
foreach(int i in numbers)<br />
{<br />
    if(i>0) c++;<br />
}</p>
<p>而如果在C#3.0中，使用 lambda表达式，代码就可以缩减到这样一个语句：</p>
<p>int c = numbers.Count(x => x>0 );</p>
<p>其中，Count() 是数组类型的一个方法，它的参数是一个lambda表达式，通过这个lambda表达式可以过滤参加统计的元素，就是说，只有大于零的元素才进行统计，这样，一句话就可以非常清晰地完成了上面的任务。</p>
<p>而这仅仅还是一个非常简单的要求，如果是这个例子的要求更复杂一些：“将一个整数数组中的所有正数选出来，各自求出其平方，然后按大小排序，构造出一个新的数组”。那么这段程序可就需要做不少事情了，首先要对数组中的所有元素进行过滤，筛出大于0的数，然后每个数求出他的平方，然后对他们进行排序，并且要构造一个新数组并填充结果。而在C#3.0中，通用可以使用一个语句完成上面的任务：</p>
<p>int[] n =  numbers.Where(x => x>0 ).Select(x=>x*x).Orderby(x=>x).ToArray();</p>
<p>可以看到，上面的语句中，出现了3次 lambda表达式。Where、Select、Orderby这个三个方法调用，分别实现了过滤、平方、排序，他们都是以 lambda表达式作为参数传递到方法中，可见它的灵活和方便。</p>
<h3>lambda表达式的数学来历</h3>
<p><img width=100 align=right style="padding-left:10px;" src="http://upload.wikimedia.org/wikipedia/en/thumb/a/a6/Alonzo_Church.jpg/225px-Alonzo_Church.jpg"/>我们看到了lambda表达式的作用，很容易我们会想到，为什么他们叫做“lambda”表达式这个“奇怪”的名字呢？实际上，这就倒回去80年了，在计算机还处于“纸上谈兵”的年代，20世纪30年代，美国数学家阿隆佐.丘奇（Alonzo Church， 1903 – 1995）给出了一套用于研究函数定义和应用的形式系统，称为&#8221;<strong>λ演算</strong>&#8220;（lambda calculus）。</p>
<p>如果没有学习过相关内容，要完整地理解 lambda 演算，并不是很容易的一件事。这里给出一个最简单的例子，在 lambda 演算中，每个表达式都代表一个只有单独参数的函数，这个函数的参数本身也是一个只有单一参数的函数，同时，函数的值是又一个只有单一参数的函数。函数是通过 lambda 表达式匿名地定义的，这个表达式说明了此函数将对其参数进行什么操作。</p>
<p>例如，一个函数 f(x) = x + 2 ，这是我们都很熟悉的书写方式，表示自变量（参数）为x，函数的值为“x+2”。如果用 lambda 演算表示，他的形式就变为了： λ x. x + 2。这里λ是一个固定的符号，后面的x表示参数，圆点后面表示函数的值是x+2，而 f(3) 的值写作 (λ x. x + 2) 3。更多的 lambda 表达式 相关的内容，这里不再介绍，可以参考<a target="_blank" href="http://zh.wikipedia.org/wiki/%CE%9B%E6%BC%94%E7%AE%97">wiki百科</a>中相关的介绍。</p>
<p>那么如果仅仅是这么性形式上更换一个写法，当然也就没有什么实际意义了，而这么做的巨大意义在于，基于这样一套非常简明的规则，可以把“计算”这件事说清楚，即什么是可以计算的，以及如何使用通用的方式描述一个“计算”的过程？</p>
<p>就好象CSS为了描述页面布局，而设计出一套“盒子模型”，它是把页面布局中的最通用、最基本的一些特征提取出来，形成的若干规则。同样，&#8221;<strong>λ演算</strong>&#8220;是一套“计算的模型”，它是对计算的本质特征的描述。 lambda 演算与现代的计算机之间，还看不出直接的联系。而到了阿隆佐.丘奇的学生阿兰.图灵（Alan Turing）的时候，就把二者直接关联起来了。</p>
<p><img style="float:right; padding:0 0 10px 10px" width="100" src="http://learning.artech.cn/wp-content/uploads/2009/04/turing.thumbnail.jpg" alt="阿兰.图灵" /> 图灵机（英语：Turing Machine，又称确定型图灵机）是英国数学家阿兰·图灵于1936年提出的一种抽象计算模型，其更抽象的意义为一种数学逻辑机，可以看作等价于任何有限逻辑数学过程的终极强大逻辑机器。</p>
<p>也就是说，图灵“从理论上”设计出了现代的计算机，并给出了计算机的具体运行方式。而这个运行在“纸面上”的计算机，仅仅用几行文字就可以描述清楚。在图灵发表了他的关于图灵机的理论十年之后，真正的计算机被真正制造出来。直到今天，我们使用的计算机，本质上看，不管你用的是“奔腾”还是“酷睿”，仍然都是在在图灵机的模型上建立的，这就是数学的力量。人类的最重要的思维能力之一是“抽象”的能力，牛顿从苹果落地“抽象”出万有引力定律，图灵从千变万化的计算中“抽象”出图灵机，包括CSS的设计者从页面布局中“抽象”出合资模型，本质都一样的，就是从纷繁复杂的表象之中，看到了隐藏在现象背后的本质的规律。</p>
<p>由此，我们可以看到，数学的作用，正是从纷繁复杂的现象中寻找事物最本质的规律。</p>
<p>至于Lambda表达式，C#中引入并不算早的，在它之前，就已经有很多现代的编程语言中都实现了Lambda表达式。更为重要的是，我们当前进行开发，大多使用的C语言为代表这类过程性语言，实际上，还有一大类编程语言，与之区别甚大，称为“函数式语言”。</p>
<p>比如现在很热门的Erlang，以及很古老的Lisp，在国外大学教学中非常流行的SCHEME，甚至微软都已经推出了自己的函数语言F#。而全世界的第一个函数语言，就是这个并非为计算机设计的&#8221;<strong>λ演算</strong>&#8220;。实际上，在计算机高级语言出现之初，函数语言和过程性的语言是同时开始的，但是几十年来的普及程度，过程性语言远远超过了函数式语言，具体原因大概是函数语言并没有过程性语言方便。但是世道就是这样有趣，随着计算机硬件的发展，现在多核CPU的出现和普及，并行计算的要求越来越高，又使得函数式语言的优势大大增加，从而使函数式语言大为热门。所以，研究历史、对比当前，发现到问题的本质，实在是很有趣的一件事。</p>
<p>如果对编程语言感兴趣，可以参考《<a target="_blank" href="http://learning.artech.cn/20090425.programming-language-intoduction.html">编程语言的入门科普</a>》和《<a  target="_blank"  href="http://learning.artech.cn/20090429.programming-language-axonomy.html">编程语言分类学</a>》。</p>
<h3>再看C#中的lambda表达式</h3>
<p>上面我们了解了C#新引入的“lambda表达式”这个特性，以及他的来历和数学基础，也简单演示了一下在C#中使用“lambda表达式”的作用，但是如果仅仅是为了节省几个循环语句，是代码简洁一些，就太小看了“lambda表达式”的作用。实际上微软引入“lambda表达式”的意义远不止于此，还有更大作用，这里就不再深入研究了。</p>
<p>写过一些程序的，比如用C语言或者C++、C#语言的读者有没有考虑过一个问题，尽管我们在程序中计算一个表达式的值很容易，比如这样一句话：</p>
<p>int x=3*(2+3);</p>
<p>就给x这个变量赋值为15了。</p>
<p>但是如果要您写一个程序，实现用户输入一个数学表达式的字符串，然后计算出结果，可就不那么容易了。写一个能够计算加减乘除、带有括号的四则运算的程序，至少要在计算机系学到3年级的《编译原理》课程，才够用的。为什么呢？因为里面包含了很复杂的逻辑的，比如你需要能够把一个字符串，解析为运算的操作数和运算符号，同时还要考虑，先乘除后加减的规则，以及括号的处理。若你可以没有学习任何相关基础的情况下，自己能够成功地写出这样一个程序，说明你绝对是个非常非常聪明的人。</p>
<p>理论上说，计算机程序中包括两个部分：“数据”和“指令”，当我们把一个四则运算的表达式存储在字符串中的时候，它仅仅是一些数据，而不是指令，要真正计算出结果，需要把这个数据转换成指令，才能够进行计算。</p>
<p>因此，如果从更深层次看待这个问题的话，C#引入“lambda表达式”、以及“表达式树”这几个新特性以后，从基础层面，在“数据”和“指令”之间搭建了一座桥梁，可以非常方便地相互转化。当一个表达式的逻辑通过“表达式数”以数据的形式保存以后，就可以方便地对他进行各种操作。具体内容这里不再详细讨论。</p>
<p><img style="float:right; padding:0 0 10px 10px" width="80" src="http://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Anders_Hejlsberg.jpg/200px-Anders_Hejlsberg.jpg" alt="Anders Hejlsberg" />当然这方面还有很多工作可做。实际上，由Anders Hejlsberg主持的C#语言从1.0到即将发布的4.0，一直保持着相当快速的的前进步伐，C# 1.0实现了代码的托管，C# 2.0实现了泛型，C# 3.0引入了LINQ，C# 4.0将引入动态特性。一步一个脚印，而且每一个新特性都为后面的发展打下了坚实基础。</p>
<h3>总而言之</h3>
<p>在上面，我们结合C#语言中的一个特性，说明了一下它背后的数学背景。可以看出以下的一些结论，希望对读者有所帮助：</p>
<h4>计算机科学的本质是数学</h4>
<p>计算机成为一种科学，其实历史很短，不过几十年的时间。尽管现在的计算机已经成了日常消费品，而当初计算机科学的先驱们可都是大数学家。当然现在计算机以及软件开发已经成为了一个巨大的产业，很多很多工作，都不需要数学家才能胜任了。否则，依靠着几个数学家，这么多事情可做不过来啊。</p>
<p>但是有一点我们要认清的是，越是重要的、底层的、基础性的工作，和数学的关系越密切。因此，我们作为普通人，可以看看自己的能力到哪层，就去寻找适合子的工作。</p>
<h4>软件开发人员要学到什么程度才够用呢？</h4>
<p>就像上面我提到的，现在整个产业已经变得巨大无比，因此层次也非常多，已经不存在一个明确的界限了，无论你有的基础如何，总是可以找到适当的位置的。当然，如果你希望做一个程序员，数学还是一个需要重要因素的。做程序的人数学不好，就好象唱歌不认识乐谱，或者绘画不懂素描，对你的影响是很大的，</p>
<p><strong>至于应该如何学习数学？我的感觉是： 1）先侧重于“广度”，2）然后再有重点地考虑“深度”，3）最重要的是提高学习能力。<br />
</strong></p>
<p>第一句话的意思是：先侧重于“广度”的意思是，你先不管能理解多少，至少把那写必备的基础，都略知一二，即使不是真懂，至少也要知道一些重要的概念、大原则、大的思考方法。</p>
<p>第二句话的意思是：然后再考虑“深度”的意思是，在大致了解的基础上，在找一些相对直接有用的，深入地学习。</p>
<p>第三句话的意思是：任何人都不可能什么都掌握，很多东西都是在用到的时候，才会去具体研究学习，因此学习能力才是最重要的。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090811.web-dev-maths-basic.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>随心随笔 (4)—— 做网站比的是慢功夫</title>
		<link>http://learning.artech.cn/20090806.create-content-site-abc.html</link>
		<comments>http://learning.artech.cn/20090806.create-content-site-abc.html#comments</comments>
		<pubDate>Thu, 06 Aug 2009 09:04:22 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[随心随笔]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090806.create-content-site-abc.html</guid>
		<description><![CDATA[我们自己的这个“前沿视频教室”网站做了也有不到3年的时间了，虽然还是一个很小的小站，但是也通过这个网站，认识了很多没有见过面的朋友，也通过这个网站，和很多网友、读者经进行... ]]></description>
			<content:encoded><![CDATA[<p>我们自己的这个“前沿视频教室”网站做了也有不到3年的时间了，虽然还是一个很小的小站，但是也通过这个网站，认识了很多没有见过面的朋友，也通过这个网站，和很多网友、读者经进行了非常愉快的交流，甚至还有通过这个网站成为我们项目开发的客户的朋友，挺让我感到惊喜的。</p>
<p>我们的大多数内容都是说技术方面的问题，今天来说说做网站的一些不完全和技术相关的体会。</p>
<p>今天不拿自己的网站做例子，而是用一些我们的“学以致用”计划的会员朋友的情况，来分析分析。我们去年年中的时候，考虑到网站的目标读者大多数都是对网页设计、制作、网站开发，比较有兴趣的朋友，特别是初学者，希望有一些可以实践的空间，因此为大家提供了一个我们叫做<a target="_blank" href="http://talking.artech.cn/thread-1003-1-1.html">“学以致用”虚拟主机计划</a>，给会员朋友提供一个空间。在这一年中，有不少参与者积极加入了这个计划。因此，我可以非常清楚地知道，这些会员用这些空间，做了哪些事情。因此从中又发现了一些现象，今天和大家一起分享一下。</p>
<p>大体上来说，我们的空间有三种用途： 企业建站、个人建站 、实验平台。</p>
<p>对于企业建站，和实验平台，我这里就不详细说了，这里重点说说第二类，个人建站，这类网站大多数是一些爱好者建立的了。我这里有两点想法，和大家分析：</p>
<p><strong>1：搭建系统很容易，能真正把网站做得干干净净、清清爽爽却并不容易。</strong></p>
<p>现在有各种各样的CMS系统，安装也很容易，因此，想做一个内容网站，技术上来说，没有什么难度，然而，实际情况是，真的等作出一个干干净净、清清爽爽、文字图片样式都严谨细致的网站那的人，却并不多。这里面一方面可能是由于还是初学者，所以技术能力还不是很好，所以建议大家，努力提高自己的技术水平。另一方面，就是态度问题，比如对细节的把握等等，这个就需要大家不断地鞭策自己了。</p>
<p>2：用各种复杂的CMS系统做个人网站的，很少有能做出实质性内容网站的，<strong>用Wordpress这样简单系统的会员，倒确实做出了一些相当不错的站</strong>。</p>
<p>这里涉及到一个CMS系统的选择问题。很多初学者，经常会问，用什么CMS系统来搭建网站？他们中的大多数，选择第一标准是“功能强大”，希望做出一个强大的网站的心情可以理解，但是，其实真正最重要的一点被忽略了——你应该找到最“适合”你的系统。这句话是一个放之四海而皆准的原则，比如说：你要找的太太，不是最漂亮的女人，而是最适合你的那个，这样才会幸福。你要找的先生，不是最有钱的男人，而是最适合你的，这样才能开心。你要找的找工作、你要交朋友、你要买房子、你要买汽车……诸如此类，不都是这样吗？你要找的网站内容管理系统，也不是功能最强大的，而是最适合你的。</p>
<p>确实有很多CMS系统，功能非常强大，但是问题是：</p>
<p>1：<strong>功能越强大、越多、越灵活，你使用起来越复杂、越麻烦，你需要的学习成本就越高</strong>，你要自己配置很多参数、修改样式、修改设置、修改栏目，都非常复杂，而对于一个初学者，你怎么搞的定呢？</p>
<p>2：即使搞定了，这么一个大系统已经搭建起来了，一大堆的栏目、子栏目需要你往里面填内容，你到哪里去找这些内容呢？就好象皇帝住在紫禁城，那是因为他有三宫六院陪他住，还有大小太监为他服务，紫禁城对他一点也不大，而您就一个平头老百姓，有0或1个老婆，奢侈一点的，能有个小时工给你收拾收拾屋子，给你紫禁城去住，不但没有用，而且不得累死你吗？<strong>你必须要有足够的生产出来的内容，来满足这个网站结构的需要。</strong>当然，有的人使用各种方法去找别人的内容放到自己的网站上，但是这样的网站，有谁会看呢？</p>
<p>反而我看到几位会员，使用相对非常简单的Wordpress，做出了非常不错的网站，内容也很充实，都是原创的文章，我会经常去看一看，会感到很有收获。为什么呢？</p>
<p>1：因为Wordpress系统非常简单，立即就可以上手，添加内容、分类、存档等等，都非常简单，因此，非常容易就可以上手，成就感立竿见影。</p>
<p>2：Wordpress简单，但并不缺少灵活性，基于Wordpress的系统，可以通过不同层次的深入设置、修改、二次开发，产生出令人惊讶的结果。这个就看你是不是愿意不断地花功夫了，虽然也需要努力，但是有一点很重要，就是它可以在增加内容的同时，慢慢研究、慢慢改进。这个过程是非常有价值的过程。</p>
<p>这里给出来两个例子，他们都是我们学以致用计划的会员，他们的网站都符合我认为的“<strong>干干净净、清清爽爽、有充实内容</strong>”的标准</p>
<p><a target="_blank" href="http://www.17css.com/ ">http://www.17css.com/ </a>这是青色网友的网站，内容非常不错，我前两天看到似乎是一个美国公司的人在青色的站上留言，邀请他去工作呐，我不知道青色有没有深入了解过这个具体情况，我看他们中国的办公室是在北京，我倒是欢迎青色来北京工作啊！</p>
<p><a target="_blank"  href="http://www.keelii.cn/ ">http://www.keelii.cn/ </a>这也是我们老朋友的一个网站，无论是形式和内容，也都非常不错。</p>
<p><strong>做网站其实是个慢功夫，是马拉松，不能着急，不能急功近利。</strong>技术只一个工具，最终还是要靠人来把它做好。不仅仅对于根据兴趣爱好，建立网站的爱好者如此，即使是对于一些企业，建立门户网站，以及内部的信息管理系统等等情况，莫不如此。由于我们平常的主业就是给一些企业开发系统，包括企业的对外门户网站，和内部的信息管理系统，我们也会反复和客户沟通，并不断地让客户理解一点，系统能不能真正发挥作用，和企业的应用方式有直接的关系。做网站，就像养孩子——只管生，不管样，那是不行的。</p>
<p>我就看到，有一些会员朋友一开始非常有兴致，安装好了各种CMS系统，无论是Wordpress这样比较简洁的，还是更为强大的CMS系统，很多人并没有真正能用起来，甚至有的会员的网站安装好什么样子，现在还什么样子，过了一年，域名也过期了，网站也没法访问了。</p>
<p>总之，做网站要坚持，我看到有的会员朋友在一年里，换了几次域名，换了几次不同的CMS系统，如果是为了试验着玩，没有问题，但是我还是建议，最好能够实实在在地看准一个目标，坚持不动摇，一直把它做到底，坚持到底，就是胜利，不要浅尝辄止，做几天就换方向，做几天就换目标、做几天就换方法，<strong>这样都不利于你积累以前的工作和努力</strong>。就好象工作，千万不要轻易地尝试彻底转行，把一个工作真正理解深刻，做到底，就会比所有人都强。<strong>一旦换行业，你就是一个新手，一切都用从头来，以前积累的经验都清零了，这是对自己人生的最大浪费，千万那要慎重。做网站也是同理的。</strong></p>
<p>好了，今天就说这么多吧，希望对大家有所帮助！如果你对建立一个自己的技术博客感兴趣，可以参考我以前写的这篇文章：<a href="http://learning.artech.cn/20090427.how-to-write-blog.html">如何写好技术博客</a></p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090806.create-content-site-abc.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Web开发杂谈(6) ——Web开发的入门建议</title>
		<link>http://learning.artech.cn/20090803.web-dev-abc.html</link>
		<comments>http://learning.artech.cn/20090803.web-dev-abc.html#comments</comments>
		<pubDate>Mon, 03 Aug 2009 02:58:59 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[Web开发杂谈]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090803.web-dev-abc.html</guid>
		<description><![CDATA[前几天，一位网友boovit 留言，提出了关于后台（服务器端程序）开发的一个问题，一直有不少读者有类似的问题，因此，我结合我自己的一点体会，介绍一下。需要指出的是，后端技术和前端... ]]></description>
			<content:encoded><![CDATA[<p>前几天，一位网友boovit 留言，提出了关于后台（服务器端程序）开发的一个问题，一直有不少读者有类似的问题，因此，我结合我自己的一点体会，介绍一下。需要指出的是，后端技术和前端技术（HTML/CSS/Javascript）相比，要复杂得多，范围也广得多，因此学起来肯定是需要更多的精力和时间的。boovit网友的问题说到：</p>
<div style="background:#EEE">
<p>“老师：我现在已经开始看有关asp开发后台的书了，我想先把这个搞清楚。老师能不能给我建议一些好的图书或着是网站。还有给我一些学习上的指导，使我更快、更好的掌握后台开发。 谢谢老师了！”</p>
</div>
<p>下面我来谈谈体会。</p>
<h3>1：必不可少的理论基础</h3>
<p>我曾经写的一篇小文章<a target="_blank" href="http://learning.artech.cn/20090418.how-to-learn-web-dev.html">《Web开发杂谈(1) —— 学习开发的三个层次》</a>中，已经谈到了学习开发，应该有三个层次。</p>
<p>今天主要谈的是第二个层次，不过这里先稍微说说第一个层次的问题——大学计算机专业的基础课。 其实这个层次就是靠上学解决的，如果自学，也同样就是买一些教科书，回家苦读，做习题，把几本书的习题都会做了，就算过关了。具体课程各个大学也都是大同小异的。这里也可以列出一些基本的专业基础课，都应该学习一遍的：数据结构、计算机组成原理、汇编语言、数据库基础、操作系统原理、编译原理 。可以看到我列出的这5门课，大都是“原理”，就是在于这是让学生真正了解计算机内部机制的课程。其他一切应用都是在这些原理的基础之上的。因此，想做一名合格的开发人员，至少要把这基本吃透。当然实际上，大学4年的课程远不止这些，如果有兴趣，不妨都学一下，但是上面列的这5们，实在是太基础了，一定是必修的。</p>
<p>如果说再基础一些，就涉及到“数学”的问题了，实际上，计算机专业的课程表中，大致上会有5门左右的数学课：高等数学、线性代数、概率论与数理统计、离散数学、数值分析。可以说，这些课程就是上面的基础课的基础课了。如果是理工科专业的学生，大致上也都学过，如果没学过，最好也下点功夫，数学不仅是专业的基础，而且是思维方式的基础。大多数人，对数学都很头疼，不过还是应该尽可能多学一些的。</p>
<p>好了，因此建议你至少把这10门课程踏踏实实学下来。用武侠小说的说法，这些都是“内功”，有了这些内功，再去学一些“招式”，就容易太多了，可参考<a target="_blank" href="http://learning.artech.cn/20090701.xuzhu-and-gump.html">《虚竹的人生启示》</a>。用中国文化的说法，叫做“道”与“技”之间的关系。用自然辩证法的说，叫做“科学”与“技术”之间的关系。都一个道理。</p>
<h3>2：下面再说说第二个层次——开发必备的工具</h3>
<p>有了上面第一个层次的“内功”，而没有一些实际的招数，就好象虚竹空有无涯子70年的内功，却不会使用。因此，还需要掌握一些实际的开发工具，这样就可以做出很多实际的项目了，就好象武林高手可以上阵了。</p>
<p>对于Web开发来说，大致分为前端和后端，前端就是在浏览器上运行的程序，主要是Javascript程序，后端就是在服务器运行的程序，种类就非常多了。目前，Web开发的主流的“三巨头”是.net、Java和PHP。</p>
<p>首先要注意的是，不用过于花精力探讨哪个更好。没有哪一个是最好的，只有最适合你的那一个。至少在5年内，他们都会存在并发展，你只要把任何一个掌握精通，都有绝对的实力去赢得胜利，就像无论那本武侠小说，&#8221;少林&#8221;和&#8221;武当&#8221;都是大门派。只要选择一个适合你的就可以了，比如你周围有个PHP高手，你可以随时请教，那你就学PHP就好了。能随时请教，比任何事情都重要，对你的帮助一定是最大的。</p>
<p>下面分几个方面来说一说：</p>
<p><strong style="color:#900">1：过硬地掌握一门编程语言：</strong>比如你用 ASP.net ，那就掌握C#或者VB，用PHP，就掌握PHP。语言的掌握，就是靠不断的实践，写够了5万行代码，自然就掌握了。</p>
<p><strong style="color:#900">2：掌握一个开发环境</strong>：当然说到开发环境，比如Windows上的Visual Studio是超级强大的，实际上这里说的开发环境，除了能够写程序之外，更重要的是掌握足够的调试经验，这个同样也是需要实践经验磨练的，和上一条一样，写够了足够多的行数，自然你的调试经验就丰富了。</p>
<p><strong style="color:#900">3：过硬的SQL语言基本功</strong>：Web开发，绝大多数离不开数据库，所谓Web程序，绝大多数都是根据需要，把一堆数据，按照要求存储到数据库中，在需要的时候，再取出来，并显示的好看一些（怎么存取由后台决定，怎么显示好看，由前后台共同决定），就可以了。因此，小到一个留言簿，大到一个超级大系统，都离不开数据库的支持。因此，SQL语言，一定要搞熟，要能够根据各种稀奇古怪的要求，写出正确的SQL查询语句，这也是个功夫，需要不断积累一些经验。</p>
<p><strong style="color:#900">4：基本的数据库的配置、管理经验</strong>：上面第3条说的是能够用SQL语句在程序中访问数据库，此外，还需要一些对数据库的配置、管理经验，理论上说，有一个专业的说法，叫做DBA，数据库管理员，专门做这个，但是作为开发人员，多少也需要了解一些，至少基本的配置管理操作要了解，至少要熟悉一种数据库系统，比如SQL Server、My SQL等。</p>
<p><strong style="color:#900">5：对网络机制的理解</strong>：要做Web开发，和以前开发的单机运行的程序相比，一个最大的区别，就是有存在客户端和服务器的分别。用户在浏览器上，按了一个按钮，可能的结果是先在客户端运行了一些Javascript代码，然后又传到服务器上，服务器又开始运行一些代码，然后把一些数据传回到客户端，结果客户端又开始运行另一些Javascript代码，最后才给用会显示出正确的结果。那么这个过程，你就必须要非常清楚，在什么时刻，什么条件下，在哪里，运行了哪个程序的哪行代码。 这和以前在一台计算机上一个程序，从第一行运行到最后一行，是很不一样的。</p>
<p>这里的关键问题是，一定要对HTTP协议，有一定的了解，比如你一定要清楚 “请求”和“响应”分别是怎么回事，服务器和浏览器之间是如何传递数据，并协同工作的。这个不用了解的非常深入，但是至少要在概念上非常清楚，否则无法深入理解Web开发的实质。</p>
<p><strong style="color:#900">6：对“领域问题”有比较好的理解力</strong>：所谓“领域问题”，就是你要开发的系统，实现的具体功能是什么，比如你做一个“学生学籍管理系统”，那么就要对学校管理学生的具体方法、制度、规则深入、完整地理解，然后才能设计出一个合适的系统，适合这个需求，理论上来说，这个工作就比较“高级”了，在一个团队中，常常有“系统分析员”或者“系统架构师”的说法，其实也没有那么玄乎了，只是一定要真正能够理解用户的需求，才能做出一个正确的选择。因为客户并不懂技术，就要靠系统分析人员，来理解用户的需求。这一步做不好，结果将会导致整个项目陷入泥潭，后果不堪设想。</p>
<p>7：本质上来说，有了上面前5点，已经完全可以做一名很好的Web开发人员了。第6点已经不仅仅限于技术层面了。我们这里当然主要谈技术，就技术层面来说，还有两点值得一提，对于Web开发特别有用。</p>
<p>下面两点的重点都是提供开发人员的开发效率。都是对于广大战斗在第一线的“码农”来说，基本上没有什么其他成本，唯一的成本就是你的时间，所以要想尽办法提高你的生产效率。用这几天时髦的说法：“哥卖的不是代码，卖的是时间！”</p>
<p><strong style="color:#900">A：Web开发框架。</strong>所谓框架，就是根据一些相对通用的、固定的开发模式，设计出的一套程序库，开发人员可以直接利用这些框架提供的程序进行开发，从而大大减少工作量。在上面说的“三巨头”中，各自都有很多不同的框架，适用于不同类型的开发需求。在对Web开发有了一定的经验以后，就可以使用一些框架，来加速你的开发效率，即所谓提高你的“生产力”。比如在.net平台上，最近微软推出的 ASP.net MVC ，就属于这样的一个Web开发框架，实现了MVC模式的开发，当然MVC在JAVA上，和在Ruby on Rails前几年已经有了相应的框架。在这种框架上做开发，具体为什么可以提供生产效率，就不是本文篇幅可以说完的了，有兴趣的读者，可以自己了解一下。</p>
<p><strong style="color:#900">B：数据访问层的开发效率加速。</strong>实际上，统计表明，现在大多数Web开发工作，绝大部分工作是围绕着数据库中的数据的增、删、改、查来进行的。这些工作本质上都是通过SQL语言实现的，因此上面的第3点中，特别提到了“过硬的SQL语言”的功夫，对一个开发人员的重要性。然而，最近几年出现了不少数据访问层的开发框架，有一个通用的名称叫做“ORM”即“对象关系映射”框架，它的作用就是通过易于理解的高级语言支持的面向对象的操作方式，避免或减少编写难于理解、管理的SQL语句，从而可以大大提高开发和调试效率。同样，在“三巨头”上，有各自的不同的实现。比如.net上的 Linq To SQL，以及Entity Framwork都是这样的工具，使用他们以后，可以使开发人员不再直接编写，或减少直接编写SQL，可能会少量地降低运行的效率，但是可以大大提升开发效率。因此，对于开发人员来说，这些工具，也是值得关注的。还是那句话：对于程序开发来说，基本上没有什么其他成本，唯一的成本就是你的时间，所以要想尽办法提高你的生产效率。</p>
<p>当然，ORM不是万能的，大多数情况下，如果没有SQL基础，使用ORM还是会有问题，特别是效率问题。这就好像如果你有汇编语言的基础，再写C语言的代码，和不懂汇编的人写出来的，肯定是不一样的。</p>
<p>=====================</p>
<p>最后谈一下关于boovit提到的 ASP还是ASP.net的问题，这个我还是多少有些了解的。从ASP入门也是一个不错的选择，因为ASP和ASP.net相比，更接近于Web的本质，ASP.net（非MVC）的WebForm模式，已经使得他的开发不像是Web开发了，尽管省事，但是封装了太多的细节，使得上手很容易，深入很难。</p>
<p>而如果你使用纯的ASP做一些开发，更容易了解Web的本质机制。有了这个了解之后，再使用更方便的开发方式，比如ASP.net MVC，甚至是 WebForm模式的ASP.net，都会更容易深入到本质层面。特别是是如果从ASP转到 ASP.net MVC，你会发现你的感觉好像扔了自行车，换成了法拉利。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090803.web-dev-abc.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>随心随笔(3)——给教师朋友的关于CSS的几点教学建议</title>
		<link>http://learning.artech.cn/20090706.css-teaching-adivse.html</link>
		<comments>http://learning.artech.cn/20090706.css-teaching-adivse.html#comments</comments>
		<pubDate>Mon, 06 Jul 2009 01:54:52 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[随心随笔]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090706.css-teaching-adivse.html</guid>
		<description><![CDATA[据我们的了解，目前大中专院校关于Web设计方面的课程，大致上还都是在以Dreawmeaver为线索的三剑客软件的介绍这个阶段。
实际上，无论是从技术发展的角度，还是以实际应用角度考虑，这都... ]]></description>
			<content:encoded><![CDATA[<p>据我们的了解，目前大中专院校关于Web设计方面的课程，大致上还都是在以Dreawmeaver为线索的三剑客软件的介绍这个阶段。</p>
<p>实际上，无论是从技术发展的角度，还是以实际应用角度考虑，这都是有点滞后了。目前已经有一些对Web标准和CSS等新技术比较有兴趣的院校和老师，已经开始把目光移向了符合Web标准的教学内容。我觉得这无论是对教师，还是对于学生，都是是一件大大的好事。</p>
<p>前几天收到一位教师朋友的来信：</p>
<div style="background-color:#EEE">“您好！我是一名教师，曾经看过你们编写的一本关于css的书，觉得写得很详细很条理，所以一直很关注你们。</p>
<p>目前大多数的教材都是针对不同的知识点举不同的例子，给人的感觉是很零散，不知您那有没有一本这样的教材：全书以一个例子贯穿始终，具体详细的介绍某个网站的制作过程，通过这一个例子讲解不同的知识点。我觉得这样的教材能让学生在学完之后对网站建设有一个整体的感觉，而且由于整本书是一个具体的例子，可以调动学生的学习热情，学完之后有成就感，同时为他们自己再学习作别的网站时有足够的信心。”</p>
</div>
<p>我们以前写过各种各样的内容的计算机图书，对于实用技术而言，如您所说的“案例教学”是一个非常好的方法，这是肯定的。但是对于编写教材，希望用“一个大案例”贯穿全书，是比较困难的。也可能有更好的处理方法。</p>
<p>关于基于Web标准的教学课程，我个人有以下几点考虑：</p>
<p> 1：在CSS中，最重要的四大核心基础是： 盒子模型、标准流、浮动、定位，如果把这4个基础真正搞懂了，那么所有的案例实际上都是在在这4个基础之上的应用。而讲清这四个基础，最好是使用非常干净的，小巧但是非常能够体现原理本质的小案例来说明。实际制作的案例往往为了要出一些效果，加入很多非本质的东西，最好作为理解了基础以后的操作实践，否则我担心教学很容易陷入泥潭。我建议一定要先把这4个核心基础扎扎实实地讲清楚，否则想要做出一些效果会非常困难。</p>
<p>2：从写书的角度，我们会希望各个章节之间的独立性要强一些，而如果后面的章节都是依赖于前面的章节的案例，那么读者在学习的时候，会比较麻烦，他必须严格从前往后看，稍微跳一点，就很麻烦。 对于教学而言，同样，如果把案例限制的太死，对于教师使用也会带来麻烦，书上的案例最好还是作为启发性的，可能对于学生和教师，都更灵活一些。</p>
<p>3：相对于一个大案例贯穿的模式，我更倾向于这样一种模式：每节有几个小案例，每章有一、两个中案例，最后放几个大案例。在方便的情况下，后面的案例可以使用前面的案例作为“零件”。实际上，教学案例的设计，对于教学的效果，至少占70%的影响。</p>
<p> 4：我不知道您现在手里有哪本书，如果有<a href="http://www.ptpedu.com.cn/HomePage/Detail.aspx?id=12795" target="_blank">《CSS网页设计标准教程》</a>或者<a target="_blank"  href="http://learning.artech.cn/20080213.css-exploring-published.html">《CSS网页设计彻底研究》</a>的话，我觉得那个顺序是非常清晰合理的一个教学过程，您说的用一个大案例作为贯穿的想法，虽然教材不一定容易实现，但是在您的实际教学中是完全可以实现的，用的例子不一定是书上的，我们可以额外制作一些，这个其实非常简单。</p>
<p>5：上面一点中提到的两本书的教学顺序，比《精通CSS+DIV网页样式与布局》一书更合理一些，更注重对核心原理的分析和讲解。</p>
<p>6：我有时间以后，可以准备一些考虑比较全面的案例，作为教学用例，提供给大家，大家在教学时，如果觉得合适可以用在课堂上，或者留作作业。手头有几个经过时间考验的案例，就可以用好多届学生了，每年只要做一些改进即可。老师可能教学的负担现在都很重，我个人建议，对于每一门课，真正关键是搭建一套适合自己思路的教学计划和配合的案例，这件事一定要真正花大力气做一次，以后就好办了。</p>
<p>7：“CSS禅意花园” 这个网站的思路非常非常好，在世界范围内对于CSS的普及都有着巨大的影响，非常值得借鉴，我在视频教程里对此有详细的介绍，我觉得完全可以把它用在您的教学中，对您所说的“调动学生的学习热情”，绝对是可以大有帮助的。对于爱学习的学生，肯定会喜欢；而对于不爱学习，只是想糊弄的学生，你无论使用什么办法，他也不会感兴趣的，我觉得这类学生还是很多的，您只要对那些想学习的学生认真负责就可以了。 不知您是否看过  <a target="_blank" href="http://learning.artech.cn/category/css-research">http://learning.artech.cn/category/css-research</a> 这套视频教程，这是我自己简单制作的，里面有关于“CSS禅意花园”的介绍，供您参考。</p>
<p>8：此外，不知道您面对的学生大致是什么基础。CSS的教学比传统的Dreamweaver为主的方式，我估计难度还是大不少，需要真正理解CSS的核心思想才可以。Dreamwever和HTML基本上不存在逻辑问题，也不需要调试，而CSS虽然不是编程语言，但是还是多多少少有一些逻辑在里面，另外，调试也是很多非计算机专业学生难于理解和掌握的事情，而CSS要真正做好，需要一些简单的调试能力。</p>
<p>9：CSS是非常重要的技术，现在用的越来越普及，我觉得应用在教学中还是值得尝试的。</p>
<p>10：如果您是大专院校的相关课程的任课教师，可以到<a target="_blank" href="http://www.ptpedu.com.cn">人民邮电出版社的教学资源服务网站</a>，免费申请<a href="http://www.ptpedu.com.cn/HomePage/Detail.aspx?id=12795" target="_blank">《CSS网页设计标准教程》</a>和<a target="_blank" href="http://www.ptpedu.com.cn/HomePage/Detail.aspx?id=12753">《网页制作综合技术教程》</a>的样书，他们的工作人员会与您核实身份后给您免费邮寄这两本书。请注意要用真实身份申请，他们只能提供给大专院校的教师，需要验证申请者的真实性。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090706.css-teaching-adivse.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>你问我答（38）—— 问答精选集</title>
		<link>http://learning.artech.cn/20090703.selected-faq.html</link>
		<comments>http://learning.artech.cn/20090703.selected-faq.html#comments</comments>
		<pubDate>Fri, 03 Jul 2009 02:03:51 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[你问我答]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090703.selected-faq.html</guid>
		<description><![CDATA[我在过去时常会根据一些读者和网友的问题，做出一些回答。有时也会根据我自己遇到的问题，写一些相关的文章。今天把一些经常常被问到的问题，做一个分类整理，这样既可以便于初学者... ]]></description>
			<content:encoded><![CDATA[<p>我在过去时常会根据一些读者和网友的问题，做出一些回答。有时也会根据我自己遇到的问题，写一些相关的文章。今天把一些经常常被问到的问题，做一个分类整理，这样既可以便于初学者了解，同时也方便我回答一些常遇到问题，可以直接把文章发给提问者，总之希望提高效率，对大家有所帮助。</p>
<h3>1：关于学习目标、学习方法、学习态度等通用的问题</h3>
<p><a target="_blank" href="http://learning.artech.cn/20071129.web-career-plan.html"><strong>《关于Web设计、制作、开发工作》</strong></a>：“Web”相关的工作实际上包含的内容非常广泛，此文主要针对这些工作进行具体的分类，进行一些介绍，帮助读者找到自己的定位，和学习的方向。</p>
<p><a target="_blank"  href="http://learning.artech.cn/20090418.how-to-learn-web-dev.html"><strong>《学习开发的三个层次》</strong></a>：本则是针对Web“开发”的学习给出的一些建议，供打算作程序员的朋友参考。</p>
<p><a  target="_blank" href="http://learning.artech.cn/20071023.how-to-learn.html"><strong>《每天被问得最多的一个问题》</strong></a> ：此文主要是针对“非常初学”的初学者，学习一些基本的技术和软件操作时，做出的一个简单的难度估计。</p>
<p><a  target="_blank" href="http://learning.artech.cn/20081015.what-to-learn.html"><strong>《上大学，学什么？》</strong></a>：此文主要针对学习“基础理论”和“实用技术”二者之间的关系，做出一些分析，帮助读者理清学习思路。</p>
<p><a  target="_blank" href="http://learning.artech.cn/20081125.self-teaching-is-hard.html"><strong>《自学是艰苦的》</strong></a>：此文主要针对学习方法的一些建议，同时对自己的学习能力的评估做出一些分析。</p>
<p><a  target="_blank" href="http://learning.artech.cn/20081024.job-responsibility-1.html"><strong>《工作职责兼谈工资水平（上）》</strong></a> 和 <a  target="_blank" href="http://learning.artech.cn/20081025.job-responsibility-2.html"><strong>《工作职责兼谈工资水平（下）》</strong></a> ： 这两篇文章主要谈了谈Web前端的工作职责，至于里面说到的工资水平，是我“闭门造车”想出来的，不一定和实际相符，但就我个人实际做一些项目的了解，现在普遍的情况是：略知皮毛的人非常多，真正做的好的人却相当不多，所以工资到底多少合适，就看你的真正的真功夫了，是“非常多”里面的？还是“相当少”里面的？</p>
<p><a  target="_blank" href="http://learning.artech.cn/20090701.xuzhu-and-gump.html"><strong>《虚竹的人生启示》</strong></a>：本文是针对<a  target="_blank" href="http://learning.artech.cn/20081015.what-to-learn.html">《上大学，学什么？》</a>一文的读者交流的一个后续文章，对学习“基础理论”和“实用技术”二者之间的关系，也就是“内功”和“招式”之间的关系的一个补充说明。</p>
<h3>2：关于CSS在不同浏览器中的兼容性问题</h3>
<p><a  target="_blank" href="http://learning.artech.cn/20071119.css-browser-debug.html"><strong>《关于CSS在不同浏览器的调试经验》</strong></a>：本文介绍了两个调试CSS网页的最基本的原则。</p>
<p><a  target="_blank" href="http://learning.artech.cn/20080129.css-debug-skills.html"><strong>《CSS调试技巧五则，兼谈“提问的艺术”》</strong></a>：本文介绍了五个调试CSS网页的技巧，同时对如何在互联网上需求帮助给出了一点建议。</p>
<p><a  target="_blank" href="http://learning.artech.cn/20080203.firefox-ie-css-hack.html"><strong>《再谈浏览器的兼容性》</strong></a>：很对初学者听说了CSS的&#8221;Hack&#8221;这个词以后，都非常向往，其实它并不是解决问题的真正的良药。所以上面两篇文章都没有提及Hack的方法，而这篇文章则给出了一点通用性很强的Hack技巧，在你实在没有办法的时候可以考虑使用，但是尽量不用。</p>
<p><a  target="_blank" href="http://learning.artech.cn/20090316.ie-tester-recommendation.html"><strong>《CSS调试工具推荐 —— IE Tester》</strong></a>：IE的不同版本之间的差异是令设计师最为头疼的事情，本文介绍了一个方便的小工具，可以便于你在一台机器上同时用多种IE浏览器测试你制作的网页。</p>
<h3>3：CSS学习中其他通用的问题</h3>
<p><a  target="_blank" href="http://learning.artech.cn/20081210.select-css-book.html"><strong>《选择CSS参考书的建议》</strong></a>：本文针对我们出版的几本CSS图书，进行一些说明，解释了我们在写作中的一些想法和构思，便于希望跟随图书学习的朋友选择。</p>
<p><a  target="_blank" href="http://learning.artech.cn/20071105.css-slide-door-application.html"><strong>《CSS滑动门技术的简单应用》</strong></a>： “滑动门”这个词是被很多人误用的，本文使用一个简单的例子，说明了CSS中“滑动门”的含义。</p>
<p><a  target="_blank" href="http://learning.artech.cn/20081026.inline-and-blcok-level.html"><strong>《行内元素与块级元素》</strong></a> ： 行内元素与块级元素是CSS中两个非常核心的概念，非常重要，本文作一简要说明。</p>
<p><a  target="_blank" href="http://learning.artech.cn/20081211.css-dictionary.html"><strong>CSS英文小字典</strong></a> ：对于很多人来说，学习CSS的一个很大的困难，不是因为CSS难以理解，而是因为CSS中的英文单词太多。这里我总结了一个“CSS英语小字典”，pdf格式，读者可以下载，一共有160个单词，如果您对英语实在不灵光，可以花几天时间，集中背一次。</p>
<h3>4：关于基于CSS的建站完整流程</h3>
<p><a  target="_blank" href="http://learning.artech.cn/20080320.web-design-work-flow.html"><strong>《你问我答(22)——遵循Web标准的网页设计工作流程》</strong></a>，此系列完整地介绍了一个网站的设计、制作全过程，共分5个部分：<a  target="_blank" href="http://learning.artech.cn/20080320.web-design-work-flow.html"><strong>第一部分</strong></a> 、<a  target="_blank" href="http://learning.artech.cn/20080321.web-design-work-flow-2.html"><strong> 第二部分</strong></a> 、<a  target="_blank" href="http://learning.artech.cn/20080322.web-design-work-flow-3.html"><strong>第三部分 </strong></a>、<a  target="_blank" href="http://learning.artech.cn/20080323.web-design-work-flow-4.html"><strong>第四部分</strong></a> 、<a  target="_blank" href="http://learning.artech.cn/20080324.web-design-work-flow-5.html"><strong>第五部分</strong></a>。 </p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090703.selected-faq.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>随心随笔(2) —— 虚竹的人生启示</title>
		<link>http://learning.artech.cn/20090701.xuzhu-and-gump.html</link>
		<comments>http://learning.artech.cn/20090701.xuzhu-and-gump.html#comments</comments>
		<pubDate>Wed, 01 Jul 2009 02:40:10 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[随心随笔]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090701.xuzhu-and-gump.html</guid>
		<description><![CDATA[今天早上，看到一位网友的发言：

温老师好：
看了您的这篇文章，我受到很多启发。但我有点不明白，如果在大学花时间把理论学的很好了，当走出大学的时候，那也只是一个有理论知识的... ]]></description>
			<content:encoded><![CDATA[<p>今天早上，看到一位网友的发言：</p>
<div style="border:1px solid #999; padding:0 20px;">
<p>温老师好：</p>
<p>看了您的这篇文章，我受到很多启发。但我有点不明白，如果在大学花时间把理论学的很好了，当走出大学的时候，那也只是一个有理论知识的人，而那些公司要的是能做出产品的人，学好离散数学，数字逻辑，数据结构，编译原理，计算机组成，系统原理，操作系统等但没学 html/Css/js/asp.net/photoshop,等实际能做出产品的技术，那样走出大学能找到工作吗？</p>
<p><strong style="color:#C00">就像《天龙八部》里的虚竹，无涯子把 70年的内功都传给他，但他不会招式，不一样也不能克敌致胜吗？</strong></p>
</div>
<p>这位网友的思考还是蛮有趣的。首先，借用网上的一段话简单总结一下虚竹的人生吧：</p>
<div style="border:1px solid #999 ; padding:0 20px;">
<p>虚竹同学恐怕是金庸学堂里英雄班中最让人不服气的一个。</p>
<p>论相貌，“浓眉大眼，一个大大的鼻子扁平下塌，容貌颇为丑陋”，做人迂腐呆板，口齿笨拙，琴棋书画不精（也就围棋懂点皮毛），既无段誉同学的玉树临风才艺双绝，亦无慕容复同学的俊雅清贵博学多才，更没有萧锋同学的豪迈刚雄智勇双全。</p>
<p>论出身，原也就是个少林寺的低级蓝领，后来总算找到亲生父母了，才发现自己是个生活作风犯了严重错误的少林掌门的私生子；母亲却是残害婴儿的四大恶人之一，单其社会危害性就是枪毙十次都不够。虚竹同学，真是要人才没人才，要文凭没文凭，要出身没出身。</p>
<p>虚竹同学的入学成绩，可谓惨不忍睹，烂到极点，恐怕也只有比韦小宝同学略好一点。假若让MM们票选金庸学堂里最不理想的情人，恐怕虚竹同学将是英雄班里得分最高的一位。</p>
<p>可就是这么一位落后生，毕业成绩却是英雄班里名列前茅的。看其成绩单，让人惊讶：</p>
<p>1、美女科，100分。毕业成绩是娶到西夏国公主，梦姑的容貌虽然没有正面的描写，有正面提及的仅是她的侍女的容貌，按慕容复同学的观点，这位侍女“虽比王语嫣似乎稍有不及，却也是千中挑、万中选的美女”。侍女已经如此靓丽了，更不用说公主了，只有更好不会更差。天山童姥也说她“端丽秀雅，无双无对”。所以梦姑之貌美打100分不为过。</p>
<p>2、财富科，98分，作为西夏国的驸马，虚竹持有西夏国国库的股份，而单公主的嫁妆就可以入选当时的亚洲富豪榜前列了，再加上其作为当时天下最大的黑道邪 教的实际控制组织灵鹫宫的唯一CEO，其控制的天下黑钱恐怕不比朝廷的少。西夏国的部分财富和灵鹫宫控制的黑钱合计，应该会比段家富，但至少比慕容家富是肯定的了。</p>
<p>3、权势科，98分。虚竹同学结交和控制的势力黑白两道都有，且不说西夏国的势力范围，单灵鹫宫管辖和控制的黑社会势力就已经遍及海外，管辖范围就比现在的阿扁牛b多了；加上他还有大理的结拜兄弟段誉段皇爷，因此虚竹同学毕业后走遍天下都有人照应，权势远胜姑苏慕容复同学。</p>
<p>4、武功科，99分。在虚竹同学的身上，汇集了无崖子70年的内功、天山童姥和李秋水的十之八九分真气，掌握北冥神功、天山折梅手、天山六阳掌、小无相功、生死符五项逍遥派武功绝学，功夫在当时可与萧峰齐肩。从少室山之战轻松擒拿丁春秋老流氓一战来看，虚竹同学的武功当时已经可以忝居天下前三甲了。</p>
<p>5、才艺科，90分。虚竹同学更气人的是还有一手医学绝活，治疗一般棍棒刀枪的外伤或内力所致的内伤是没有任何问题的，连阿紫的眼珠都可以移植，说明其已掌握人体器官移植手术的秘密。这些绝招在手，行走江湖肯定也是会比别人多了好几条命，F D是肯定不怕的，禽流感也不在话下，寿命恐怕也是所有英雄同学中最长的一位。</p>
</div>
<h3>内功与招数</h3>
<p>下面在具体说说，虚竹的到70年内功之后，金庸的说法：</p>
<div style="border:1px solid #999 ; padding: 20px;">
<p>童姥道：“你武功虽低，但无崖子的内力修为已全部注入你体内，只要懂得运用之法，也大可和我的对头周旋一番。这样罢，咱们来做一桩生意，我将精微奥妙的武功传你，你便以此武功替我护法御敌，这叫做两蒙其利。”也不待虚竹答应，便道：<strong style="color:#C00">“你好比是个大财主的子弟，祖宗传下来万贯家财，底子丰厚之极，不用再去积贮财货，只要学会花钱的法门就是了。花钱容易聚财难，你练一个月便有小成，练到两个月后，勉强可以和我的大对头较量了……”</strong>。</p>
</div>
<p>在这里，金庸实在是举了一个超级精妙的例子：<strong style="color:#C00"> 练内功=聚财（挣钱），练招数=花钱，花钱容易聚财难！</strong></p>
<p>换到我们这里，就是说，你苦学 离散数学，数字逻辑，数据结构，编译原理，计算机组成，系统原理，操作系统 这些课程就是在练内功，在聚财，而学习那些具体的技术，无非是在花钱而已，练内功很难，而如果有了内功，这些技术的掌握都是很容易的事情了。</p>
<p>这里必须插一句题外话，我自己无数次想过如何举一个最合适的例子，能偶恰当地说明“内功”和“招数”之间的关系，今天才发现金庸随手举的一个例子竟然这么贴切，真是服了！</p>
<h3>人生的态度是“内功的内功”</h3>
<p>上面，我们只说了武功中的内功，实际上金庸写的虚竹这个人物，已经不仅仅是在说武功这点事了，如果你看过一个美国电影《阿甘正传》（如果没看过，强力推荐），你会发现，东西方的价值观在这里得到了统一，<strong style="color:#C00">虚竹和阿甘有着惊人的相似，都是资质极差，性情木纳的人，但是他们具有着共同的特点：淳朴、善良 、执着</strong>。</p>
<p>凡世人认为“聪明”的事，他们都不会做，而他们做的事在世人眼里却是“傻”事。《天龙八部》里有一个作为对比的慕容复，《阿甘正传》里有一个最为对比的珍妮；我甚至怀疑，《阿甘正传》的编剧是不是一个金庸的读者。</p>
<p>所以，人生的态度才是“内功的内功”。我们现在的中国人，都太“聪明”了，拼命做着 一些“聪明”的事情，却偏离了人生本来的意义。让我们都傻一些吧！</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090701.xuzhu-and-gump.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>你问我答(37)——jQeury实现回车键代替Tab键</title>
		<link>http://learning.artech.cn/20090622.return-repalce-tab-jquery.html</link>
		<comments>http://learning.artech.cn/20090622.return-repalce-tab-jquery.html#comments</comments>
		<pubDate>Mon, 22 Jun 2009 03:29:19 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[你问我答]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090622.return-repalce-tab-jquery.html</guid>
		<description><![CDATA[昨天和青色同学聊了几句，说到一个具体的技术问题，我觉得可能有一些普遍性，这里详细说一说。
问题要求
问题是这样的实际的情境：对于一个网页上的表单，放置了一个提交按钮以后，用... ]]></description>
			<content:encoded><![CDATA[<p>昨天和<a target="_blank" href="http://www.17css.com/">青色同学</a>聊了几句，说到一个具体的技术问题，我觉得可能有一些普遍性，这里详细说一说。</p>
<h3>问题要求</h3>
<p>问题是这样的实际的情境：对于一个网页上的表单，放置了一个提交按钮以后，用户如果按了键盘的回车键，默认情况下，就会提交这个表单了。这样对于用户输入各个表单项目，会很不方便，输入完一个项目，或者用鼠标选择下一个项目，或者用键盘的Tab键选中下一个项目。</p>
<p>现在希望实现的要求是：</p>
<p>1：如果当前处于焦点（也就是用户正在输入的那个文本框）不是最后一个输入框，那么按回车键时，将焦点转移到下一个输入框；</p>
<p>2：如果当前处于焦点（也就是用户正在输入的那个文本框）是最后一个输入框，那么按回车键时，将请用户确认后提交表单；</p>
<h3>基本思路</h3>
<p>这个问题使用jQeury实现是很方便，这里面主要有两个问题需要解决，</p>
<p>1：判断按键是否是回车建， 这个比较好办，用jQeury中的 keypress 事件，就可以获取到当前按的键的值了，回车键的值是13，比较一下即可。</p>
<p>2：判断当前处于焦点的输入框是不是最后一个输入框。</p>
<p><a target="_blank" href="http://learning.artech.cn/uploads/blog-files/return-demo.htm">点击这里查看最终效果参考</a></p>
<p>说明：如果对Javascript和jQeury完全不了解的读者，最好先学习一下相关的基本知识：<a target="_blank" href="http://learning.artech.cn/20080621.mastering-javascript-jquery.html ">http://learning.artech.cn/20080621.mastering-javascript-jquery.html </a>。我们这里就不解释最基本的概念了。</p>
<h3>实现方法</h3>
<p>下面是具体的代码，首先是非常简单的HTML代码，可以看到，一个form元素，里面有三个输入框，和一个提交按钮，输入框分别设置了id属性。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre>&lt;form id=&quot;myform&quot;&gt;
&nbsp;
&lt;label&gt;first name : &lt;/label&gt;&lt;input type=&quot;text&quot; id=&quot;firstName&quot; name=&quot;firstName&quot; /&gt;
&lt;label&gt;last name : &lt;/label&gt;&lt;input type=&quot;text&quot; id=&quot;laseName&quot; name=&quot;laseName&quot; /&gt;
&lt;label&gt;addess : &lt;/label&gt;&lt;input type=&quot;text&quot; id=&quot;address&quot; name=&quot;address&quot; /&gt;
&nbsp;
&lt;input type=&quot;submit&quot; value=&quot;submit&quot; /&gt;
&nbsp;
&lt;/form&gt;</pre></td></tr></table></div>

<p>接下来是Javascript代码了：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><pre class="javascript">        $<span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#123;</span>
            $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;#myform input:text&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">keypress</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>e<span style="color: #66cc66;">&#41;</span>
            <span style="color: #66cc66;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>e.<span style="color: #006600;">which</span> == <span style="color: #CC0000;">13</span><span style="color: #66cc66;">&#41;</span>                         <span style="color: #009900; font-style: italic;">//判断所按是否回车键</span>
                <span style="color: #66cc66;">&#123;</span>
                    <span style="color: #003366; font-weight: bold;">var</span> inputs = $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;#myform&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">find</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;:text&quot;</span><span style="color: #66cc66;">&#41;</span>;                   <span style="color: #009900; font-style: italic;">//获取表单中的所有输入框</span>
                    <span style="color: #003366; font-weight: bold;">var</span> idx = inputs.<span style="color: #006600;">index</span><span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>;      <span style="color: #009900; font-style: italic;">//获取当前焦点输入框所处的位置</span>
&nbsp;
                    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>idx == inputs.<span style="color: #006600;">length</span> - <span style="color: #CC0000;">1</span><span style="color: #66cc66;">&#41;</span>     <span style="color: #009900; font-style: italic;">// 判断是否是最后一个输入框</span>
                    <span style="color: #66cc66;">&#123;</span>
                        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000066;">confirm</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;最后一个输入框已经输入,是否提交?&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>   <span style="color: #009900; font-style: italic;">//用户确认</span>
                            $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;#myform&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">submit</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;    <span style="color: #009900; font-style: italic;">//提交表单</span>
                    <span style="color: #66cc66;">&#125;</span>
                    <span style="color: #000066; font-weight: bold;">else</span>
                    <span style="color: #66cc66;">&#123;</span>
                        inputs<span style="color: #66cc66;">&#91;</span>idx + <span style="color: #CC0000;">1</span><span style="color: #66cc66;">&#93;</span>.<span style="color: #000066;">focus</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;       <span style="color: #009900; font-style: italic;">//设置焦点</span>
                        inputs<span style="color: #66cc66;">&#91;</span>idx + <span style="color: #CC0000;">1</span><span style="color: #66cc66;">&#93;</span>.<span style="color: #006600;">select</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;       <span style="color: #009900; font-style: italic;">//选中文字</span>
                    <span style="color: #66cc66;">&#125;</span>
&nbsp;
                    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span>;<span style="color: #009900; font-style: italic;">//取消默认的提交行为</span>
                <span style="color: #66cc66;">&#125;</span>
            <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>下面具体解释上述代码。</p>
<p>说明：如果对Javascript和jQeury完全不了解的读者，最好先学习一下相关的基本知识：<a target="_blank" href="http://learning.artech.cn/20080621.mastering-javascript-jquery.html ">http://learning.artech.cn/20080621.mastering-javascript-jquery.html </a>。我们这里就不解释最基本的概念了。</p>
<p>第1行：说明一下代码在页面完全装入浏览器以后执行。<br />
第3行：对表单中的输入框设置keypress事件，注意参数中函数带有一个参数，将通过它获取当前按键的数值。<br />
第5行：判断是否是回车键，如果不是，则不作任何处理，如果是怎进入下面的代码。<br />
第7行：获取表单中的所有输入框，以便判断当前的输入框是否是最后一个。<br />
第8行：获取当前输入框在扁担的多有输入框中处于第几个。<br />
第10行：判断是否是最后一个输入框。<br />
第12-13行：如果是最后一个，那么显示一个确认框，如果用户确认，则提交表单<br />
第17-18行：如果不是最后一个，那么将下一个输入框设置为焦点，并将其中的文字选中<br />
第21行：取消默认的提交表单操作。</p>
<h3>问题小结</h3>
<p>1：可以看出，jQeury对我们写前段程序，确实非常方便，可以说jQeury的出现，改变了我们写Javascript程序的方式，就像C语言的出现，我们不再用汇编那样一个字节一个字节计算内存。</p>
<p>2：从效率角度，第7行代码，可以放到第3行的前面，这样，就不用每次都搜索一次DOM元素，不过实际体验不出速度的变化。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090622.return-repalce-tab-jquery.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>网页设计杂谈(17)——大多数设计师将成为自由职业者</title>
		<link>http://learning.artech.cn/20090616.freelancer-trends.html</link>
		<comments>http://learning.artech.cn/20090616.freelancer-trends.html#comments</comments>
		<pubDate>Tue, 16 Jun 2009 02:34:57 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[网页设计杂谈]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090616.%e7%bd%91%e9%a1%b5%e8%ae%be%e8%ae%a1%e6%9d%82%e8%b0%8817%e2%80%94%e2%80%94%e5%a4%a7%e5%a4%9a%e6%95%b0%e8%ae%be%e8%ae%a1%e5%b8%88%e5%b0%86%e6%88%90%e4%b8%ba%e8%87%aa%e7%94%b1%e8%81%8c%e4%b8%9a.html</guid>
		<description><![CDATA[先说几句题外话，最近一个多月忙一个项目，导致无暇顾及这个网站，没有新教程、新文章、回答读者的问题都拖了一个多月，昨天我把积压了的一个月的问题回复完了。
最近手头还有3个项目... ]]></description>
			<content:encoded><![CDATA[<p>先说几句题外话，最近一个多月忙一个项目，导致无暇顾及这个网站，没有新教程、新文章、回答读者的问题都拖了一个多月，昨天我把积压了的一个月的问题回复完了。</p>
<p>最近手头还有3个项目，8月份应该可以全部完成，我们计划完成这几个项目以后，暂时不接新的项目了，拿出一段比较完整的时间，主要任务是，把做的这几个项目中的一些技术问题总结回顾一下，提高一下认识，实际工作中很多问题都是应急的，未必是最好的方法，而阶段性的总结和回顾，就像下棋的人经常做的一件事——“复盘”，是很重要的。此外，将写一两本书，现在出版计算机图书的经济收益大不如前，不能作为写书的动力了，不过我还是很喜欢写书这件事本身的。既是对自己的提高，也可以帮助一些初学者，是很好的事情。</p>
<p>昨天在回复问题的时候，看到了<a target="_blank"  href="http://blog.junghae.cn/2009/04/why-most-designers-will-be-freelancers-within-20-years/"> Junghae 同学的Blog</a>，他希望和我们的网站做链接，我已经加上了。Junghae 同学是学设计的，我很喜欢他作品的风格，他很努力、很踏实，也很有思想，我也很喜欢这一点。我看到他提到了国外网站上的一篇文章——“<a  target="_blank" href="http://freelancefolder.com/why-most-designers-will-be-freelancers-within-20-years/">Why Most Designers Will Be Freelancers Within 20 Years</a>”（为什么在二十年内，大多数设计师将成为自由职业者），我看了一下，觉得说的挺有道理，这里把其中的一些观点翻译成中文，共相关的读者参考。此外，我认为，不仅仅是设计师，其他以智力和创意为根本的职业，我相信都会走上这条道路。</p>
<p>我是很反对直接使用他人的内容的，不过今天破一下例，借用一些原文的内容，因为：1）我认为我自己写出来的不如原文好，2）原文是英文的，我希望介绍给英文不是很灵光的读者朋友。以下是我意译而非完全直译的内容。 译文的下方是我看过此文以后，自己的一些想法。</p>
<p>==============以下为译文====================</p>
<p>最近在设计工业领域，已经出现了一个大趋势——各个层次的设计师都开始转向成为“自由职业者”。然而，这个趋势比很多人想象中的更大，更快。不久的未来，设计师的主体，将由自由职业者构成。</p>
<p>你可能会问，这是什么原因导致的呢？其中有三个主要的原因。</p>
<h3>1：自由职业的成本明显下降</h3>
<p>由于信息技术的发展和成本的迅速降低，大力推动了“在家工作”这种方式的蓬勃发展。</p>
<p>就现在来说，在家中建立一个办公室，可能只需要几千块钱，而仍然可以和全世界沟通并协同工作。技术成本已经较过去几年大大降低，其结果就是，现在可以用比原来少的多的成本，建立有效的自由职业的商业模式——这意味着更多人可以成为自由职业者。（遗憾的是在中国，至少是北京，规定民宅不能注册公司，即使是个人设计公司这样完全不扰民的公司也不可以，这真是很滑稽的龟腚）</p>
<p>比如Skype，单单这一个工具，就为成千上万的自由职业者与他们的客户跨越国界地交流，由于Skype的出现，更多的人开始建立基于自由职业的工作方式。跨国的沟通成本是多少？可能是25块钱的一副耳机罢。（说到这里我想到，就在现在，我们正在手头的一个项目的客户就是在英国的，我们之间的所有交流都是基于Email和Skype的。去年和一个芬兰设计公司合作了很久，效果也很好。）</p>
<p>这些新技术的发展，以及持续的成本降低，激发了自由职业方式的成长和普及的风暴。因此，我们有理由相信，在为若干年内，它还将继续把很多人拉到自由职业者的圈子里。</p>
<h3>2：很多公司开始雇佣自由职业者，代替传统的雇员</h3>
<p>由于全球性的经济衰退仍在持续，越来越多的公司需要消减成本——以及裁员。这些公司需要降低成本，而维持办公室和全职雇员的开支是非常高的。</p>
<p>而另一方面，如果雇用自由职业者，这些维持性的成本都不需要了。特别重要的是，如果雇主接到一个大项目，可以迅速灵活地雇佣更多的自由职业者加入项目，而在没有项目的时候，可以没有任何支出。这是最灵活，伸缩性最好的按需解决方案。很多公司逐渐意识到，使用自由职业者实际上是最节约成本的方式。</p>
<p>而当世界经济开始恢复的时候，或者称为“后衰退经济”时期，将会出现严重的人力短缺，谁将填补这个缺口？自由职业者。</p>
<p>当然，经过一段时间，这些“填补空缺”的自由职业者，也可能会重新回到传统的全职员工的状态。但是由于自由职业方式的低成本、年轻一代的新想法，以及由于维持员工的高成本带来的风险，这种“摇摆”不会很快发生。</p>
<p>由于上面描述的趋势，自由职业者的数量在未来若干年中，将会迅猛增长。</p>
<h3>3：年轻一代更追求自由和独立</h3>
<p>最后一个趋势是，目前设计师行业的平均年龄，大约在25~34岁，这个数值在快速的降低，即主流设计师越来越年轻。</p>
<p>这个年龄段的年轻人不再把职业仅仅作为生活的保障。看到或经历过最近几年的裁员和招聘，很多年轻人更愿意依靠自己，而不是一个大公司的承诺。再加上对独立性和未来繁荣的预期，就可以很清楚地了解为什么新一代的年轻人执着于自由职业方式，而不是得到一份朝九晚五的工作。</p>
<p>由于几乎不存在的技术门槛，加之全球性的经济衰退作为恰到好处的“催化剂”，以及一群追求独立的年轻人，可以很清晰地看到，设计工业正处于迅速变化的时期，这种变化还将持续几年或几十年。</p>
<p>二十年后，可能设计工业的主体将由自由职业者构成。</p>
<h3>你准备好了吗？</h3>
<p>你准备好了应对之策吗？你已经建立自己的生意以面对未来的竞争，以及在经济恢复以后的新生意吗？</p>
<p>或者，你认为上面的预言是错误的？或者疏漏了某些重要的因素吗？</p>
<p>和大家分享一下你的想法吧！</p>
<p>==============以下为我个人的想法====================</p>
<p>总体上来说，我同意上文的预言，事实上，从我身边的很多人，已经可以非常清晰的看到这种趋势了，在一个单位里稳定上班的人，越来越少了。当然，作公务员的不算，中国目前日益明显地把社会分为了“体制内”和“体制外”这两个部分，二者各自有着完全不同的游戏规则。每个人根据自己的价值取向，以及其他各方面的因素，比如家庭背景等等，进入其中一个赛场。</p>
<p>1：“自由职业者”这个概念，并不是说只有一个人在单打独斗，一个人的能力总是有限的，事实上自由职业者之间同样可以形成配合良好的团队，因此同样可以完成有规模的项目。事实上国外已经出现了彻底没有“领导”，而完全基于合作模式的的商业公司，当然这对于我们中国的传统意识，还是很难做到的。</p>
<p>2：“自由职业者”的自由，是选择的自由，一个理想的社会，就应该是给每个人选择的自由，而不是仅仅是遵守的自由。</p>
<p>3：从本质上来说，人类发展的大趋势就是在解放个体，从这个意义上说，自由职业者群体的迅速发展，是社会进步的表现，几千年来社会发展的历史，就是个人解放的历史。</p>
<p>4：自由意味着约束，权力意味着责任。在一个不自由的社会，这两点都很难做到。</p>
<p>5：自由职业者要具有更强的“解决问题”的能力，否则还是在大公司打工更舒服。</p>
<p>5：即使是在公司里给老板打工，也可以把自己看作是“一个人”的公司，你的老板就是你的客户，如果你无法让老板满意，你也无法让客户满意。永远给自己打工，而不是给老板打工。90%的人意识不到这一点，比如俺太太，虽然她工作态度和能力都很好，但是总觉得自己吃亏了：）</p>
<p>==========补充说明================</p>
<p>我翻译完这篇文章后，才发现Junghae同学在他的blog已经翻译了，呵呵，我直接看的是英文，没注意到。早知道就不用翻译了，不过既然已经码了这么多字，就这样吧，他翻译得更生动，很好。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090616.freelancer-trends.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Web开发杂谈(5) ——解读 TIOBE 指数</title>
		<link>http://learning.artech.cn/20090508.meaning-of-tiobe.html</link>
		<comments>http://learning.artech.cn/20090508.meaning-of-tiobe.html#comments</comments>
		<pubDate>Fri, 08 May 2009 01:00:54 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[Web开发杂谈]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090508.meaning-of-tiobe.html</guid>
		<description><![CDATA[在上一篇文章中，我们谈到了编程语言的流行度，今天继续这个话题，专门说说TIOBE指数。
正如以前在文章中提到过，各种编程语言的粉丝们，经常在会在一些开发技术社区里，关于语言之间... ]]></description>
			<content:encoded><![CDATA[<p>在<a target="_blank" href="http://learning.artech.cn/20090506.popularity-of-programing-languages.html">上一篇文章中，我们谈到了编程语言的流行度</a>，今天继续这个话题，专门说说TIOBE指数。</p>
<p>正如以前在文章中提到过，各种编程语言的粉丝们，经常在会在一些开发技术社区里，关于语言之间的优劣进行口水大战，忙得不亦乐乎。就比如说这几天吧，就有<a target="_blank<br />
"  href="http://www.cnblogs.com/JeffreyZhao/archive/2009/04/19/why-i-do-not-like-java.html">一场关于“C# vs Java”的争论很热闹</a>。</p>
<p>当然这种争论不是完全没有意义的，这种争论通常都是拿着一方的某些优势特征，去跟对方叫板：“你看，我用XXX语言，3行搞定这个，你用YYY语言，30行也搞不定吧？”，另一方如果有办法破解，自然会说：“谁说我3行搞不定，这就给你搞一个看看！”。因此在这个过程中，无论是亲自上阵的，还是观战的，都是一个总结和分析的过程，其实对更深入地理解技术，还是有帮助的，所以如果有工夫，也有兴趣，去看看这些争论，对你了解一些语言的某些特性，也挺好，特别是可以帮助你了解一些你不熟悉的语言的特点。</p>
<p>从另一方面来说，也不必太当真。几百上千种语言，最终能成为最流行的几种语言之一，基本上就跟奥运会金牌和银牌之间的差异，真是没多大差别的。但是要指出的是，这种势均力敌，是有时间性的，也许现在势均力敌的竞争对手，几年以后就有明显的差距了。所以，如果你打算掌握一门技术来生存，最好还是能挑一个更为长久的技术和开发工具，否则如果你的工具每况愈下，总是不太好的事情。长江后浪推前浪，小心被拍在沙滩上。就像我们以前还是挺喜欢写一些计算机图书的，但是现在计算机图书市场每况愈下，也不敢太靠这个了，在网上写一些文章，也不错了，出不出书就不去管它了。</p>
<p>下图是 TIOBE 2009年4月发布的数据，最流行的10种编程语言，在近8年中的变化情况。</p>
<p><center> <a target="_blank" href='http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html'  title='Tiobe-2009-04'><img src='http://learning.artech.cn/wp-content/uploads/2009/04/tiobe-2009-04.gif' alt='Tiobe-2009-04' /></a> </center></p>
<p>具体几个数字并不关键，我们可以从大的趋势，看看哪些是上升的，哪些是下降的。首先，4个下降的分别是：Java、C、C++、Perl。</p>
<p><center><img src='http://learning.artech.cn/wp-content/uploads/2009/04/declined-languages.gif' alt='declined languages' /></center></p>
<p>首先，接下来是前8名中，另外4个，他们都是上升的分别是：PHP、Visual Basic、Python、C#。</p>
<p><center><img src='http://learning.artech.cn/wp-content/uploads/2009/04/rising-languages.gif' alt='rising-languages' /></center></p>
<p>前十名中，还有两个：Javascript 和 Ruby，他们的份额都相对低多了，都在2%多一点。Javascript的使用率大幅上升，显然是由于Web 2.0 概念推出以后，Ajax等Web前端开发技术兴起带动的。至于Ruby，在中国的流行程度还很低，在国外经过前两年的火爆增长，这两年也没有进一步的大幅提升了。</p>
<p><center><img src='http://learning.artech.cn/wp-content/uploads/2009/04/js-ruby-languages.gif' alt='js-ruby-languages' /></center></p>
<p>从上面的一些图中，我们可以看出一些问题来：</p>
<p>1：Java和C，前两名的位置依然牢固，但是使用率确实下降了很多了，C++第3名的位置岌岌可危。</p>
<p>2：大的趋势可以看出，原来的前三名遥遥领先，现在明显各种语言之间的差距明显减小了。</p>
<p>3：上面这些图不能直接叠在一起比较，因为纵坐标的刻度不一样，C#上升了很多，但是仍然远远低于Java。</p>
<p>4：如果要评选一个“稳定进步奖”，那么是非C#莫属了，8年来稳扎稳打，步步为营。</p>
<p>5：就Web开发领域来说，三巨头应该是“Java 、.NET 和PHP”，.NET 对应在上图中，不仅仅对应于C#，还包括Visual Basic，还包括很多人实际上仍然在使用传统的ASP，没有列在图中，因此，如果把三者加在一起，应该和 Java相差不多。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090508.meaning-of-tiobe.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Web开发杂谈(4) —— 编程语言的流行度</title>
		<link>http://learning.artech.cn/20090504.popularity-of-programing-languages.html</link>
		<comments>http://learning.artech.cn/20090504.popularity-of-programing-languages.html#comments</comments>
		<pubDate>Mon, 04 May 2009 01:00:57 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[Web开发杂谈]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090504.popularity-of-programing-languages.html</guid>
		<description><![CDATA[在上一篇文章中，我们从不同类别介绍了编程语言，当我们要选择学习一门编程语言时，有很多因素值得考虑，今天讨论第一个因素“流行度”。
就像我们中国人都说汉语，我们就只能和说汉... ]]></description>
			<content:encoded><![CDATA[<p>在<a target="_blank" href="http://learning.artech.cn/20090429.programming-language-axonomy.html">上一篇文章中，我们从不同类别介绍了编程语言</a>，当我们要选择学习一门编程语言时，有很多因素值得考虑，今天讨论第一个因素“流行度”。</p>
<p>就像我们中国人都说汉语，我们就只能和说汉语的人一起生活工作一样，你使用某种编程语言，就只能和同样使用这种语言的人一起工作了。当然我们也可以多掌握几门外语，那当然是最好的了！所以现在也很提倡“混合编程”，就是针对不同的问题，使用最适当的语言，来进行开发。</p>
<p>说到这里，要提到的一点是，和我们生下来无法选择母语不同，我们是可以自己选择使用的编程语言的。那么我们如何来选择要学习什么编程语言呢？这里我想第一重要的因素就是“流行”了。</p>
<p>尽管现在是强调个性化的时代，否则也不会产生那么多种编程语言了，但是作为一名普通的程序开发人员，你只会一门非常冷僻的“小语种”，你的用武之地可能就非常小了。毕竟开发往往是团队完成的，因此用越流行的语言作为开发语言，相对就更容易招聘到程序员，这样反过来，掌握越流行的语言的程序员也就比较容易找到工作，这样形成正反馈，真正“流行”的语言也就不是很多了，而且这些语言一般都是有着超强支持后盾的，比如微软支持的C#、VB，SUN和IBM等联盟支持的Java等等。这个竞争，可不是一般的公司能玩得起的游戏。</p>
<p>那么我们怎么知道各种语言，哪个更流行呢？ 这个调查是相当困难的，可能比人口普查还难得到精确的数字。不过我们了解个大概也就可以了，目前大致有三种方法可以观察各种语言的流行度：</p>
<h3>1. TIOBE 指数</h3>
<p><a target="_blank" href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html"> TIOBE</a>是一个独立的组织，每个月公布一次各种语言的流行度数据，数据来源于与世界范围内的职业程序员、教学以及第三方机构，此外流行的搜索引擎Google、MSN、Yahoo、Youtube的搜索数据也是数据的来源。他会每月公布前20名最流行的编程语言的份额。</p>
<p>比如下图就是目前（2009年4月）的数据，它显示了最流行的10种语言在近年来8 来被使用率的变化。第一名是Java，有19.34%的开发者使用。接下来使用的最多的语言是C和C++。</p>
<p><center> <a target="_blank" href='http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html'  title='Tiobe-2009-04'><img src='http://learning.artech.cn/wp-content/uploads/2009/04/tiobe-2009-04.gif' alt='Tiobe-2009-04' /></a> </center></p>
<h3>2. 招聘网站的数据</h3>
<p>招聘网站的数据也是一个评价编程语言流行度的指标，什么语言在招聘启事中出现的多，自然也就说明它更流行一些了，我们在前年的一篇文章<a target="_blank" href="http://learning.artech.cn/20071020.web-tech-trends.html">“学点什么技术好？”</a>中,介绍过一些这方面的情况。</p>
<p>下图是一个美国的网站 indeed.com 中给出的结果，indeed是一个招聘网站的搜索引擎，输入一个职业，就可以搜索到很多其他搜索网站上的招聘信息。同时还会给出一些关键字对应的招聘信息的数量。比如下图就是查“Java developer”和 “.net develpoer”的结果，看来在美国，这两者还真是势均力敌，难分高下。</p>
<p><center> <a target="_blank" href='http://www.indeed.com/jobtrends?q=%22Java+developer%22%2C+%22.net+developer%22&#038;l='  title='indeed'><img src='http://learning.artech.cn/wp-content/uploads/2009/04/indeed.gif' alt='indeed.com' /></a> </center></p>
<h3>3. 计算机图书销售的数据</h3>
<p>计算机图书被称为“IT技术市场的晴雨表”，也是一个可以反映技术发展情况的指标。只是这个数据我们一般人是无法看到的，只能是凭感觉了。不过专业人士还是可以看到的，比如美国著名的计算机专业图书出版商O&#8217;Reilly对这方面有着非常深入的研究，<a target="_blank" href="http://radar.oreilly.com/archives/2006/08/programming-language-trends-1.html">这里查看O&#8217;Reilly对这方面的一个报告</a>。下图是把美国图书市场上销售的计算机图书，根据书的内容进行归类，得到的结果，可以看到这个结果和前面Tiobe的结果，还挺接近的。</p>
<p><center> <a target="_blank" href='http://radar.oreilly.com/archives/2006/08/programming-language-trends-1.html'  title="O'Reilly"><img src='http://learning.artech.cn/wp-content/uploads/2009/04/computer-bool-sale.gif' alt='computer-bool-sale' /></a> </center></p>
<p>不过这个图已经是两年半以前的数据了，过去O&#8217;Reilly每个季度都发一个非常详细的报告，不过遗憾的是，似乎这两年来O&#8217;Reilly已经不太注意力放在图书市场上了，可能因为计算机图书市场的持续萎缩，使他们不太看重这块业务了。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090504.popularity-of-programing-languages.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Web开发杂谈(3) ——编程语言分类学</title>
		<link>http://learning.artech.cn/20090429.programming-language-axonomy.html</link>
		<comments>http://learning.artech.cn/20090429.programming-language-axonomy.html#comments</comments>
		<pubDate>Wed, 29 Apr 2009 01:00:42 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[Web开发杂谈]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090429.programming-language-axonomy.html</guid>
		<description><![CDATA[在上一篇文章中，我们介绍了一些编程语言最基本的知识，接下来，我们会分几次，介绍一些更实用的内容，重点谈谈比较常见的一些编程语言的情况，使初学者有一个宏观的了解。在你选择... ]]></description>
			<content:encoded><![CDATA[<p>在上一篇文章中，<a target="_blank" href="http://learning.artech.cn/20090425.programming-language-intoduction.html">我们介绍了一些编程语言最基本的知识</a>，接下来，我们会分几次，介绍一些更实用的内容，重点谈谈比较常见的一些编程语言的情况，使初学者有一个宏观的了解。在你选择语言的时候可以，可以做一个参考。</p>
<p>如果你以为编程语言就是我们经常听说的C、C++、Java、PHP等这么几种，那就错了。目前世界上正在被使用的编程语言数量，有数百种之多：<a target="_blank" href="http://en.wikipedia.org/wiki/Alphabetical_list_of_programming_languages">点击这里可以查看按字母排序的语言列表</a>。今天从分类的角度说说着这几百种编程语言，读者不必深究，了解了解即可。</p>
<p>人类在研究任何领域的时候，“分类”都是一个重要的课题，例如生物学，就花了很大的力气把世界上个所有生物分为“界、门、纲、目、科、属、种”若干干个层次的类别，比如我们人类就属于：“动物界 > 哺乳纲 > 灵长目 > 人科”。西方自然科学的基本思想就是“解构”，分类基本上和“解构”是一个意思。一个领域中，“分类”的水平标志着整个领域研究的深入程度。</p>
<p>所以我们在学习一个新的领域时，最好首先对这个领域中的对象的分类情况有个了解，这对于整体认识是很有好处的。就好像我们新到一个城市生活，首先找一份地图，了解一下，这个城市大概分几个区，有几条主干道，是放射状的？还是环形的？有几条地铁线路，大致什么走向，有这样一个基本的大概了解，对你日后了解这个城市就很方便。</p>
<p>下面我们就来对“编程语言”做一点“分类学研究”，再次提醒，了解了解即可。不必深究。</p>
<h3>按语言之间的承继关系分类：</h3>
<p>除了按名称排序的列表，还可以按照承继关系来进行分类，比如C++语言就是在C语言的基础上，增加以及改造了一些特性以后形成的一个新语言。<a target="_blank" href="http://en.wikipedia.org/wiki/Generational_list_of_programming_languages">点击这里查看比较完整的编程语言的承继谱系关系</a>。</p>
<p>下图是从中截取了一个分支，各语言名称的缩进表示了承继的关系：</p>
<p><center><img src='http://learning.artech.cn/wp-content/uploads/2009/04/language-family.gif' alt='Language family' /></center></p>
<p>在庞大的谱系列表中，我们之所以选择上面这一段语言分枝，因为可以看到这个分支可以说是整个“编程语言社会”中，当今最“人丁兴旺”的一个家族了。你想想看，在计算机书店里，看到的编程书，是不是大都是我用红框标示的这几种语言？他们都是这个家族中的，只是辈分不同而已，但是它们都是有共同基因的语言。</p>
<h3>按语言产生的时间分类：</h3>
<p>如果按照产生的时间来进行归类，<a target="_blank"  href="http://en.wikipedia.org/wiki/Timeline_of_programming_languages">点击这里可以查看具体编程语言的年代归类表</a>。随着技术的发展，研究的深入，编程语言也是在飞速进步的，所以晚出来的一些语言，通常会更多吸取一些以前的成功经验，避免掉一些以前的不足。</p>
<p>比如微软的 .NET平台的整体战略，就是针对Java的。.NET框架就对应于Java的虚拟机，C#也是针对着Java语言的。盖茨把Anders请到微软，操刀.NET和C#，如果单纯就语言的角度，C#确实在很多方面是比Java要更好一些，当然不是说Java不好。我对这方面也不是非常有研究，但是C#从1.0，到2.0引入泛型和匿名方法，3.0引入Linq，即将发布4.0将引入动态编称，进步实在是太大了。每一个新引入的特性都可以大大提升生产效率，而且这些改进是核心的改进，不仅仅是类库的改进。</p>
<p>但是语言的进步不像CPU的进步那样立竿见影，你把奔3的电脑换成奔4的电脑，立刻就难感觉到速度提高了。但是语言这个东西，是需要长期使用才会逐渐体会出来其中的韵味的。</p>
<h3>按语言的功能特征分类：</h3>
<p>上面这几种分类方法其实都不是最重要的，实际上对于程序员来说， 重要的是编程语言的具体行为功能特征，但是如果按照这个标准类分类，就没有非常明确、严格、一致的分类标准了，比如可以有“编译型语言”、“解释型语言”、“命令式语言”、“声明式语言”、“函数式语言”等等很多很多，总之非常复杂了，<a  target="_blank" href="http://en.wikipedia.org/wiki/List_of_programming_languages_by_category">有兴趣的可以看这里的一个总结表</a>。</p>
<p>尽管有这么复杂的分类情况，但是其实写在这里，仅仅是为了展示一下而已了，对于90%以上的开发者，以及100%的初学者，实际上都是在使用这几个非常接近的，“流行度”很高的语言，比如上面红框框里面的语言，此外可能还有一些不在红框框，但是也都是差不多的编程语言，比如Basic、Pascal（Delphi）等等，他们也都是大同小异的。所以初学者，尽可以放心，不用管它有几百上千种语言，你只要先用好这些最常用的语言，就可以啦。</p>
<p>当然，要知道，这些“流行”的语言虽然接近，但毕竟也有差异的，而恰恰是这些差异来决定你选择哪种语言，这个以后的文章再谈。</p>
<h3>思考题</h3>
<p>1： “分类”是掌握一样东西的指标，你能再举一个例子说明这个道理吗？</p>
<p>2： 你熟悉或者了解过几种编程语言，按照不同的分类标准，你能否间接一下你了解的语言？</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090429.programming-language-axonomy.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>随心随笔(1)——如何写好技术博客</title>
		<link>http://learning.artech.cn/20090427.how-to-write-blog.html</link>
		<comments>http://learning.artech.cn/20090427.how-to-write-blog.html#comments</comments>
		<pubDate>Mon, 27 Apr 2009 01:00:39 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[随心随笔]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090427.how-to-write-blog.html</guid>
		<description><![CDATA[博客是个好东西，相信每个人都看过很多人的博客。我自己发现我的新知识的来源，博客已经占有了越来越大的比例。对于非常喜欢的博客，会收录到阅读器里，每篇必读；有的则是为了临时... ]]></description>
			<content:encoded><![CDATA[<p>博客是个好东西，相信每个人都看过很多人的博客。我自己发现我的新知识的来源，博客已经占有了越来越大的比例。对于非常喜欢的博客，会收录到阅读器里，每篇必读；有的则是为了临时遇到的某个具体问题，通过搜索引擎找到的，问题解决了，也就过去了。但无论如何，在这种搜索中，都会有很大的收获。非常感谢很多博客给我带来的帮助。</p>
<h3>写技术博客的好处</h3>
<p>每一个技术人员都可以建立一个自己的技术博客，把平常的一些心得体会，实践经验写成文章，一方面这样对自己是一个很好的总结和提高，我自己的体会很深，我花了三个月的全天时间写了<a  target="_blank" href="http://learning.artech.cn/20080213.css-exploring-published.html">《CSS设计彻底研究》（台湾版名为《CSS Web设计大全》）</a>这本书，使我对CSS的理解加深了很多很多；同时写的博客文章还会对其他人有所帮助，一举两得，何乐而不为呢？</p>
<p>此外，表达能力对于一个人的职业成长道路是很重要的，表达又分为“口头表达”和“书面表达”，都非常重要。前者如在大家开会的时候，你是否能够清晰明了地阐述你的想法呢？若你有这个能力，你的领导一定对你另眼相看，书面表达”也同样，如果你写出的技术文档、总结报告，总是内容翔实、条理清晰，你升职的时间就不远了。因此，完全可以把写技术博客作为对自己表达能力的一个锻炼机会，看看自己能不能写出高水平的文章来。</p>
<p>下面根据我自己的一点思考，说几条我觉得比较重要的原则。这并没有标准的答案，每个作者都有自己的想法，无法也没有必要寻找唯一的标准答案。</p>
<h3>1：忌无关话题；贵在内容专注</h3>
<p>有的人写博客，把生活中的内容，和技术上的内容混在一起，比如和某个朋友吃了顿饭，看了一个电影，听了一首歌，工作中解决了一个问题，都写进去。如果仅仅是为了当作自己的日记本，倒是无妨。但是对于这样的写作方式，如果希望给别人看，还希望别人也能喜欢，就不太容易了。毕竟咱们不是演艺明星，就算你觉得你的生活非常丰富多彩，也到不了别人会感兴趣的程度。而且，本来你的博客可能会有一些真正高质量的内容，会很很受欢迎，也被这些无关的内容淹没了。</p>
<p>如果你希望你的博客能更受别人的欢迎，最好能够先明确一点：你知道（擅长）的什么东西，是你知道，而别人不知道，又想知道的内容？找到了这样的题材，才是你的价值所在。你把你的内容锁定在这些你的“核心武器”上，才能写出成功的博客。</p>
<p>这些内容未必是你的专业，比如你的专业是程序员，但是你非常爱好羽毛球，而且到了有一定研究的程度，那么你就完全可以以之为题材，把你作为一个普通人，从零开始，不断提高的心得体会，写成博客，可以包括很多内容，比如关于比赛规则的分析、关于练习方法的体会、关于羽毛球明星的技术动作特点等等，设定好你的读者目标，比如和自己背景相似的羽毛球爱好者，用自己的语言，认真写好，就一定会有很多忠实的读者喜欢你的博客。</p>
<p><strong style="color:#D00">一句话总结：专注、专注、再专注！</strong></p>
<h3>2：忌只言片语；贵在描述清晰</h3>
<p>我在查阅资料的时候，最郁闷的就是碰上这样的博客文章，明明他说的就是你想知道的事情，可是就是写那么一句半句，没头没尾的话，这样的博客，大多是博主为了怕自己忘记，给自己做的一个笔记，要么是一句话了事，要么是贴上一大段代码，也没有任何说明。自己明白，别人就很难明白了。</p>
<p>这样的博客同样只能当自己的日记，而无法给读者带去好感，如果要写技术博客，就应该设定一个明确的目标读者范围，为他们去写，要写某个你感兴趣的问题时，要把前言后语都说到位，把问题描述清楚，背景如何，问题在什么条件下发生，里面的根本原因是什么，然后给出符合逻辑的完善的解决方法，最后再做一下提纲挈领的总结，这样读者看后一定会感到心旷神怡。</p>
<p>就像在高考的时候，各科老师都反复嘱咐大家，回答问题的时候，一定要有中间步骤，不能只给一个结果，阅卷老师会按步骤给分。读者又何尝不是阅卷人呢？</p>
<p><strong style="color:#D00">一句话总结：是什么、为什么、怎么办，一个也不能少。</strong></p>
<h3>3：忌直接转贴；贵在亲身原创</h3>
<p>很多人看到自己喜欢的文章，就把别人的文章“复制-粘贴”到自己的博客里，分享给别人，这当然也不错，但是这种方式是没有“技术附加值”的原生态产品。</p>
<p>如果你发现了一篇好文章，完全没必要他们复制过来，“超链接”是互联网作为媒体最大的一个特点，把别人的文章地址贴到你的文章中，引用的时候，把最核心的几句话摘录到你的文章里，一定要提到是谁说的，此外，一定要确保你的文章中主体部分是你写的文字，是你的思想的表达，而不仅仅是转贴。转贴是没有任何意义的事情。</p>
<p>这就好像一个你要开一个包子铺，你买来蔬菜、肉、面粉，花了80块钱，做成包子卖出去，你收了100块钱，那么你挣的20块钱，就是把原料变成包子的“劳动的价值”。你看到了别人的文字，直接转贴，就等于你买了一堆原料，直接又卖出去，没有创造任何价值。</p>
<p><strong style="color:#D00">一句话总结：不要作知识的搬运工。</strong></p>
<h3>4：忌过度修饰；贵在文风朴素</h3>
<p>上面两种博客的缺点都是写作风格过于随意，缺少加工；而也有的少数博主正好相反，把博客当作了展示文采的舞台，虽然写的是技术问题，但是加入了其他很多东西，比如人物、情节等等。本来的目的是使自己的文章更有趣，更吸引读者。但是我个人的观点是，这样做可能没有必要，甚至画蛇添足。</p>
<p>简单一些的，编出两个人物，一个老师，一个学生，有问有答，文中穿插一些搞笑的语言， 这样还是可以接受的，毕竟对内容的干扰不是很大；更有复杂的，设计出若干人物，互相讨论，作者在写的时候，实际上花费了不少心思，为不同的角色设定不同的性格特征和“学识水平”， 但是短短的一篇技术文章，读者往往记不住那几个人物谁是谁，结果导致本来不难说清楚的事情，反而搞乱了。别人是来看你的技术内容的，而不是看笑话来的，不要过度修饰。写得再“妙趣横生”，也不能当喜剧搞笑片看吧。</p>
<p>凡是使用诙谐幽默的写法获得成功的面向大众的科普书，都是人文方面的，比如《明朝那些事儿》、《水煮三国》之类，文中加入一些小包袱，增加趣味性，其中重要的一点是，看这种书的读者本来就是抱着消遣的目的，读《明朝那些事儿》的读者，没有一个是为了研究明史的，都是为了看着玩儿的，了解一些历史典故，喝酒聊天的时候多一些素材，不会深究里面的内容。</p>
<p>而理工方面的技术书籍，就很难有人会抱着这样的心态去读。最好的博客文章应该是简单易懂，让读者花三分钟看明白，立马就能解决问题的文章。</p>
<p><strong style="color:#D00">一句话总结：不是必需的东西都删掉，一个多余字不留。</strong></p>
<h3>5：忌急于求成；贵在持之以恒</h3>
<p>什么事情做几天都容易，难的是长久的坚持。很多人建立一个博客，一开始的时候热情很高，每天都琢磨有多少人来看，没多久就发现，根本没有几个人来，绝望……深深的绝望…… 算了，没意思，不干了！！</p>
<p>所以，关键就在于你是否能够坚持，做网站不是几天的事情，不是几个月的事情，至少先做两年再看看效果。坚持提供有价值内容，坚持足够的更新频率，坚持良好的互动，总会有人喜欢你的博客的。</p>
<p><strong style="color:#D00">一句话总结： 坚持、坚持、再坚持！</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090427.how-to-write-blog.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Web开发杂谈(2) ——编程语言的入门科普</title>
		<link>http://learning.artech.cn/20090425.programming-language-intoduction.html</link>
		<comments>http://learning.artech.cn/20090425.programming-language-intoduction.html#comments</comments>
		<pubDate>Sat, 25 Apr 2009 01:11:15 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[Web开发杂谈]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090425.programming-language-intoduction.html</guid>
		<description><![CDATA[在“Web开发杂谈”系列的上一篇文章中，简单介绍了一下如果作为初学者，应该具有一个怎样的心态和预期去面对要学习的内容。就像我们新到一个陌生的城市，最需要的是一张地图；同样，... ]]></description>
			<content:encoded><![CDATA[<p>在<a target="_blank" href="http://learning.artech.cn/20090418.how-to-learn-web-dev.html">“Web开发杂谈”系列的上一篇文章</a>中，简单介绍了一下如果作为初学者，应该具有一个怎样的心态和预期去面对要学习的内容。就像我们新到一个陌生的城市，最需要的是一张地图；同样，进入一个新的技术领域，也应该尽快为自己找到一张地图，使自己有学习的方向和预期，只有这样才可能把学习进行下去。</p>
<p>实际上，我们在上一篇文章里，介绍的是一些很通用的做事方式，仔细想一想，其实做任何事情都是“一样一样”的ho~，无非都是要：1）掌握一定的知识和理论作为基础，2）并且要有实际动手操作的能力。前者即所谓的“认识世界”，后者即所谓的“改造世界”，然后再不断积累经验提升水平。对要做的事情，认识得越深刻，动起手来就越有把握。</p>
<p>不过我在上一篇文章中，把学习的过程分为了三个层次，为了避免读者的误解，这里做一些解释。尽管说，要先把基础掌握好，再去动手实践，但是并不是意味着，只顾着埋头去看那些理论，等全明白了之后再去实践。毕竟，要做的程序开发，是一个实际操作的事情，一定要两条腿走路，一边理解，一边实践，二者是相辅相成的，这样效率也会高很多。</p>
<p>因此，今天就来谈谈开发中最基础的一个话题——编程语言。就像每个人要生活在世界上，就离不开语言一样；要做软件开发工作，也是绝对离不开“编程语言”的，你的一切“改造世界”的行动，都是通过使用“编程语言”来编写程序实现的。</p>
<h3>编程语言的基本原理</h3>
<p>当今的计算机都是按照“冯.诺依曼”体系设计的，其运行的基本原理，可以简单概括为“程序存储、集中控制”这8个字，最核心的两个部分就是控制器和存储器。无论存储器是什么形态，几十年前的继电器，还是现在的DDR3内存条，程序都必须要装载到存储器中，然后控制器在时钟脉冲信号的控制下，有节奏地依次取出程序代码，执行相应的指令，周而复始。</p>
<p>而在存储器中存放的是两种信息：1）数据，即操作对象；2）程序，即操作指令。</p>
<p>因此无论你使用什么编成语言，你都是在做着同样的两件事：</p>
<p>1）告诉CPU你的数据在哪里；</p>
<p>2）告诉CPU你希望如何处理这些数据。</p>
<p>比如假设某一种计算机，有这样的一条指令：  ADD [1000]，2000 ，它的意思就是取出存储器中第1000号存储单元中的数值，让后把它增加2000，再存回第1000号存储单元。而每种计算机都有一套完整的指令集，比如Intel的 X86 CPU 和 IBM的 Power-PC CPU就具有完全不同的指令集，因此他们是不兼容的，而我们日常使用的Intel的 CPU和AMD的CPU的指令集则是兼容的。</p>
<p>而我们通常开发软件编写程序，是不会写“ ADD [1000]，2000 ”这样的代码的（这种代码称为“汇编语言”代码），而比如说，我们如果用C语言，则会写出这样的一条语句：&#8221; X = X+2000 ; &#8221;<br />
，其含义同样实现了在X这个存储单元的数值增加2000这个目的，而写起来就方便多了，用变量名称代替了存储器的编号，我们也不需要知道X这个变量到底在第几号存储单元，只要知道有这么一个位置就可以了。</p>
<p>而C语言代码是如何变成机器可以理解的代码的呢？这就需要中间有个翻译的机制，分为两种：1）编译程序，2）解释程序。</p>
<p>前者把高级语言代码彻底翻译为机器语言代码构成的程序，然后再运行；后者在运行的时候，一边翻译，一边运行。在大学的计算机本科的高年级，都会有一门课程叫《编译原理》，专门讲解这个问题。</p>
<h3>编程语言的来历和演变</h3>
<p>编程语言经历了从无到有，从低级到高级的演变过程。需要注意这里的高级和低级没有好坏之分，低级表示的更接近于机器的底层硬件，高级表示更接近于要是解决的实际的问题，而不必考虑计算机底层的运行方式。</p>
<h4>史前时期</h4>
<p><img style="float:right; padding:0 0 10px 10px" width="80" src="http://learning.artech.cn/wp-content/uploads/2009/04/turing.thumbnail.jpg" alt="阿兰.图灵" />
<p>实际上，计算机出现之前，就已经有很多数学家为计算机软件的出现打下了坚实的数学理论基础，比如著名的数学家“阿兰.图灵”和他的导师一起努力，在20世纪三、四十年代年代就创建立了“图灵机”理论，从理论上解决了计算机软件和核心——“计算复杂性”以及“算法表示”问题。前者研究“能不能计算”的问题，后者研究“如何计算”的问题</p>
<p>正是有了这样的数学理论作为基础，加上当时电子技术的突飞猛进，二者相结合，才产生了计算机这样一个划时代的伟大产物。</p>
<h4>低级语言</h4>
<p>计算机的内部处理的全都是1和0的二进制数字，表示“开”和“关”，而计算机刚刚发明出来的时候，操作人员就必须用很多真正的“开关”来操作计算机，进步一点以后，出现了“机器语言”的概念，使用例如在纸带上打孔的方式，把一些原来需要人手工拨动开关的操作序列，变成按照某种规则在纸带上的一系列孔的序列，这种打着孔的纸带可以被看作是今天的鼠标、键盘、打印机、显示器、磁盘这些东西的总和，这些东西在当年，“打孔纸带”一个人就全包了。</p>
<p>机器语言通常称为“第一代语言”，其后又产生了“汇编语言”，即“第二代语言”，汇编语言实际上就是机器语言，区别就是汇编语言中用一些符号代替0和1的序列，仅仅是便于记忆，此外，有少量的扩展功能，比如可以通过定义的“宏”来产生类似于“子程序”这样的逻辑概念，通过编写汇编语言程序产生机器代码，效率提高了很多，但是它依然是紧密依赖于机器的，和后来被广泛使用的高级语言是完全不同的。</p>
<h4>高级语言</h4>
<p>接着，历史的车轮继续开动了，所有计算工作都要转化为机器相关的代码，这个事情本身就非常复杂，因此人们就想到，能否设计出一些更接近于人类自然语言的方式，来操作计算机呢？这里要提到的两为大牛，一位叫“约翰.冯.诺依曼”，一位叫“约翰.巴科斯”。</p>
<p><img style="float:right; padding:0 0 10px 10px" width="80" src="http://upload.wikimedia.org/wikipedia/commons/thumb/d/d6/JohnvonNeumann-LosAlamos.jpg/250px-JohnvonNeumann-LosAlamos.jpg" alt="约翰.冯.诺依曼" />
<p>前者“约翰.冯.诺依曼”，可以称为“计算机之父”，美籍犹太人，数学神童出身，可以说是数学和计算机科学界的“爱因斯坦+爱迪生”，40岁以前搞纯数学研究，40岁以后把纯数学应用到应用数学、量子物理、计算机科学、核武器、经济学等各个研究领域，把数学作为工具，用得是出神入化，所向披靡。如果没有这位神人，说不定大家今天还在打算盘，呵呵（甚至比这还惨，如果没有他，也许还要晚扔那两颗牛X的原子弹）。至今的计算机（除了一些研究性质的），都没有离开“冯.诺依曼”设计的结构，所有大学生学习的计算机知识，都是基于“冯.诺依曼体系”的。</p>
<p><img style="float:right; padding:0 0 10px 10px" width="80" src="http://upload.wikimedia.org/wikipedia/commons/thumb/d/da/John_Backus.jpg/225px-John_Backus.jpg" alt="约翰.巴科斯" />后者&#8221;约翰.巴科斯&#8221;，当然也是大牛，不过从地位来讲，不能和“冯.诺依曼”相比了。他的主要贡献就是对高级编程语言的开创性工作，他认为，应该建立脱离依赖于计算机结构的程序设计语言。这里有个有流传的说法，说在1950年代，这两位“约翰”对这个问题有所争论，“诺依曼”认为不需要高级语言，而“巴科斯”认为需要高级语言。我查了查网上相关的资料，似乎没有明确的证据说明“诺依曼”认为不需要高级语言，因为“诺依曼”在1957年，年仅53岁就去世了（真是太可惜了），我没有查到他说过“不需要高级语言”这样的话，只是“巴科斯”在图灵奖获奖报告中提出了他的建立高级语言的思想而已。</p>
<p>总之，“约翰.巴科斯”建立了高级语言的思想，并设计出了世界上第一个真正意义上（至今广泛应用）的高级语言——Fortran语言。此后，就不断出现了各种各样，具有各自特点的高级语言了，这样，普通人即使对计算机的内部结构不是非常清楚，也同样可以进行软件开发了。</p>
<h3>编程语言的基本构成</h3>
<p>通常来说，一个编程语言主要包括下面三个基本组成部分：</p>
<p>1：类型系统 —— 定义了这种编程语言中使用的数据定义方式，也就是解决“操作什么”的问题。通常包括“静态类型”、“动态类型”等不同的类型系统。比如C、C++、C#、Delphi、Java等等都是静态类型语言，而Javascript、PHP、Python、Ruby等则是动态类型语言</p>
<p>2：语法规则 —— 定义了这种编程语言的流程控制方式，或者说解决“如何操作”的问题。对于过程式的语言，比如C语言，一个程序有三种流程控制结构：“顺序结构”、“分支结构”和“循环结构”。</p>
<p>3：标准库 —— 为了解决实际生活中的问题（专业说法叫做“领域问题-Domain Problem”），编程语言通常都会提供一些预备好的核心功能库，供程序员直接使用。比如你需要在程序中计算一个角度的正弦值，那么要通过基本的加减乘除这些基本运算，计算出来是很繁琐的，而这个功能有非常常用，因此，编程语言就会提供一些数学公式的计算函数库，这样程序员就可以方便地调用了。</p>
<p>说明：</p>
<p>1：实际上面的前两条是真正一个编程语言的核心，而标准库是可以扩充的，或者由第三方提供的。以.NET平台为例来说，在.NET平台上可以运行多种语言，比如C#、C++、Basic、甚至ironPHP、ironRuby等语言，每种语言都有自己的类型系统和语法规则，而他们共享同一的标准库，也就是.NET框架提供的大量已经开发好的程序库。</p>
<p>2：所谓核心就是体积比例很小，作用超大的东西。当年TruboPacal  ，后来的Delphi，再后来的C# 的设计师Anders Hejlsberg曾提到，在他的团队里，做C#语言设计的人是4个人，写C#编译器的也就几个人而已，而编写.NET框架的人就有上千人了。从中我们就可以知道“核心”的含义了。</p>
<p><img style="float:right; padding:0 0 10px 10px" width="80" src="http://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Anders_Hejlsberg.jpg/200px-Anders_Hejlsberg.jpg" alt="Anders Hejlsberg" />
<p>3：说到Anders Hejlsberg，这里必须要说一说，他也是个天才，应该是程序员做到头的终极榜样了。如果读者朋友，您不喜欢尔虞我诈的人际关系的争斗，而喜欢做单纯一些的技术工作，又没有名牌大学的博士学位，就以Anders为榜样吧，Anders是丹麦人，在丹麦上的大学（但是没有毕业，原因不得而知），到美国以后和伙伴一起开发出了Turbo Pascal，一举成名，后来在Borland公司不得志的情况下，被Bill Gates三顾茅庐，请到了微软。具体故事可以参考台湾技术作家李维的一本书《Borland传奇》，非常有趣。一名纯技术人员，能做到这样，基本上算是到头了。</p>
<h3>思考题</h3>
<p>1：本文列出了4位大牛，除了他们令人望尘莫及的天赋，你能从他们的经历中寻找到一些什么启示？</p>
<p>2：你能在头脑中想象出一个简单的程序在计算机中是如何运行的吗？</p>
<p>3：你使用哪种编程语言，你为什么选择它？</p>
<p>在下一篇文章中，我们将对目前流行的编程语言做一些介绍，使初学者有一个大致的了解，也可以帮助大家选择自己的学习路线。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090425.programming-language-intoduction.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>你问我答(36)——带有纹理的渐变背景处理方法</title>
		<link>http://learning.artech.cn/20090423.slide-door-application.html</link>
		<comments>http://learning.artech.cn/20090423.slide-door-application.html#comments</comments>
		<pubDate>Thu, 23 Apr 2009 01:00:38 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[你问我答]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090423.slide-door-application.html</guid>
		<description><![CDATA[每天收到不少问题，遇到有代表性的我就多花些时间，给出一个比较详细的回答，希望这样可以帮助更多有类似问题的读者。
问题描述

前几天有一位读者在我们的论坛上发了一个帖子，希望... ]]></description>
			<content:encoded><![CDATA[<p>每天收到不少问题，遇到有代表性的我就多花些时间，给出一个比较详细的回答，希望这样可以帮助更多有类似问题的读者。</p>
<h3>问题描述</h3>
<p><img style="float:right; padding:0 0 10px 10px;" src="http://talking.artech.cn/attachments/forumid_7/20090421_f9f139c3eddff06447b7aFBeWyMnnJSD.gif" alt="null" /></p>
<p>前几天有一位读者在我们的论坛上发了一个帖子，希望制作这样的一个网页菜单，需要使用CSS来实现。它给出了一个图示：</p>
<p>图中给出了他的切片思路，他的问题是：<font color="#CC0000">“自适应高度的 ， 上下的1和3两个部分用 img src,  中间部位“2”， 不知道怎样设置渐变色背景了，哪位大侠能给讲解一下呢， 谢谢了。”</font></p>
<h3>问题原因</h3>
<p>从他的配图，以及他的文字描述，可以看出，“表格布局”方式已经深深刻进这位读者的脑子里了，使用CSS的时候最重要的一点就是要<strong><font color="#CC0000">忘掉表格布局的思路</font></strong>。所以从这个意义上说，有些从零开始的读者学起来反而容易一些。就像一个成年人学外语很难，而小孩则容易得多，因为母语已经深深刻在我们的脑子里面了。英语老师常说的一句话是：“Think in English”。</p>
<p>CSS布局的一个最重要的原则就是，一切以内容为出发点，这个例子显然是一个很典型的列表菜单，那么它的HTML就是一个 ul 列表。我们要做的就是如何让这个ul列表具有设计图中的背景。千万不要上来就把这个图用两刀坎成三块，然后在打算用HTML和CSS拼到一起，这个思路从根本上来说，就是典型的“表格布局后遗症”~~~~。这就等于我们在说：“I&#8217;ll give you some color see see ”。</p>
<h3>基本方案</h3>
<p>那么正确的CSS思路又是如何的呢？我们做任何事情都要有一些基本的思考方法，比如从“简单到复杂”、“从特殊到一般”等等，其实你上中学的时候。这些方法都是渗透在各门课程中的，现在想一想，都会觉得很有收获。</p>
<p>比如具体到这个问题，首先考虑，如果没有渐变色，我们应该怎么办？这里因为我没有原图，就自己绘制了一个简单的，但是道理和原图是完全一样的。第一步，先从最简单的开始起步，如下面图中的左图所示，这里不存在渐变地情况。</p>
<p>下面要解决的就是一个高度自适应的问题了，那么用CSS解决自适应高度或宽度的问题，很显然要用到“滑动门”技术了。要做滑动门就要要准备好两扇“门”了，很简单，如下图中，右边的两个图所示。他们就是左边的图切片得到的，一个去掉顶部，一个去掉底部，这样当它们叠在一起，根据内容高度上下错动时，就可以产生自适应高度的背景框了。</p>
<div>
<img style="float:left; padding:0 5px"  src='http://learning.artech.cn/wp-content/uploads/2009/04/demo-bg.png' alt='demo-bg.png' /></p>
<p><img style="float:left; padding:0 5px " src='http://learning.artech.cn/wp-content/uploads/2009/04/top.gif' alt='top.gif' /></p>
<p><img style="float:left; padding:0 5px;" src='http://learning.artech.cn/wp-content/uploads/2009/04/bottom.gif' alt='bottom.gif' />
</div>
<div style="clear:both;"></div>
<p>接下来，编写HTML：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre>&lt;div id=&quot;outer&quot;&gt;
    &lt;div id=&quot;inner&quot;&gt;
        &lt;ul&gt;
            &lt;li&gt;Artech&lt;/li&gt;
            &lt;li&gt;Web Dev&lt;/li&gt;
            &lt;li&gt;Web disign&lt;/li&gt;
            此处省略若干菜单项……
        &lt;/ul&gt;
    &lt;/div&gt;
&lt;/div&gt;</pre></td></tr></table></div>

<p>这里就是把ul列表的外面套了两层div，各自作为滑动门的一扇门。如果有人要较真，非要只套一层div，而把ul作为另一扇门，也是可以的，不过这里为了简单明了，用两层div。</p>
<p>下面设置CSS样式：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="css">    <span style="color: #cc00cc;">#outer</span>  <span style="color: #66cc66;">&#123;</span>
        width<span style="color: #3333ff;">:<span style="color: #933;">186px</span></span>;
        background<span style="color: #3333ff;">:url</span><span style="color: #66cc66;">&#40;</span>images/bottom<span style="color: #6666ff;">.png</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333;">no-repeat</span> <span style="color: #000000; font-weight: bold;">bottom</span>;
        padding<span style="color: #3333ff;">:<span style="color: #933;">0</span></span> <span style="color: #933;">0</span> <span style="color: #933;">35px</span> <span style="color: #933;">0</span>;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    <span style="color: #cc00cc;">#inner</span>  <span style="color: #66cc66;">&#123;</span>
        padding<span style="color: #3333ff;">:<span style="color: #933;">35px</span></span> <span style="color: #933;">0</span> <span style="color: #933;">0</span> <span style="color: #933;">0</span> ;
        margin<span style="color: #3333ff;">:<span style="color: #933;">0</span></span>;
        background<span style="color: #3333ff;">:url</span><span style="color: #66cc66;">&#40;</span>images/top<span style="color: #6666ff;">.png</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333;">no-repeat</span> ;
    <span style="color: #66cc66;">&#125;</span>
&nbsp;
    ul <span style="color: #66cc66;">&#123;</span>
        margin<span style="color: #3333ff;">:<span style="color: #933;">0</span></span> <span style="color: #933;">20px</span>；
    <span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>解释一下代码：</p>
<p><img  style="float:right; padding:0 0 10px 10px" src='http://learning.artech.cn/wp-content/uploads/2009/04/demo-effect-1.png' alt='demo-effect-1.png' /></p>
<p>1：外层div设置一个固定宽度，就是背景图像的宽度，然后设定背景图像，注意最后一个“bottom”，表示从这个盒子的最底端开始放置背景图像。</p>
<p>2：内层div使用另一个背景图像，默认情况下就是从顶端放置背景图像，在内外层盒子重叠的部分，内层的盒子会压住外层的盒子。</p>
<p>3：下面注意，两层盒子的padding设置，外层盒子设置下部的padding为35像素，内层盒子设置上部的padding为35像素，这样就把上下装饰图像部分都让出来，而不会遮挡住他们的了。</p>
<p>4：最后，把最里面的ul列表位置调整一下，就完成了。</p>
<p>效果如右图所示，其高度可以根据ul的高度自适应。当然如果如果太高了，以致于内外两层div的背景图像无法重叠了，就会产生裂缝了，那么一种方法是把背景图像做的高一些即可，另一种方法是外面再再多套一层div，设置一个竖直方向平铺的背景，用它来填补中间的缝隙。</p>
<div style="clear:both;"></div>
<h3>渐变背景</h3>
<p><img   style="float:right; padding:0 0 10px 10px" src='http://learning.artech.cn/wp-content/uploads/2009/04/demo-effect-2.png' alt='demo-effect-2.png' /></p>
<p>下面考虑背景渐变的情况，例如上面部分（#inner）的背景图像变成右图所示的样子，而下面（#outer）部分的背景图不需要变化，可以发现，代码不需要做任何修改，结果仍然是正确的。</p>
<p>但是要注意的一点是，在这种情况下，这时列表的内容就不能太短了，如果过短的话，渐变还没有完成就直接到了下侧的颜色，如下图所示，接缝处就会不自然了。</p>
<p><center><img src='http://learning.artech.cn/wp-content/uploads/2009/04/demo-effect-5.png' alt='demo-effect-5.png' /></center></p>
<h3>增加纹理</h3>
<p><img   style="float:right; padding:0 0 10px 10px"  src='http://learning.artech.cn/wp-content/uploads/2009/04/demo-effect-3.png' alt='demo-effect-3.png' /></p>
<p>这位读者的问题中给出的图还不仅仅是渐变的问题，而且增加了纹理，这就有点麻烦了。如果仍使用上面方法则是的缺陷的，如果纹理很细小，不太明显的话，上面的方法还可以凑合了，而如果纹理比较大，就会比较明显。</p>
<p>在这里为了突出这个问题，我特意做了一个很大的纹理效果，如右图所示。可以发现，在接缝处（红色框里）就很不自然了，上下两层背景图的圆形纹理无法正好对上。按照上面的方法，这个接缝无法避免的，因为高度会自适应，所以无法确定到底它们会在什么位置接缝。</p>
<p>那么是否有更好的办法呢？要实现即有渐变色，又有纹理的背景能够自然衔接，就必须要用到半透明的背景图了，这种半透明学名叫作“alpha透明”。我们知道，GIF格式的图像是不支持alpha透明的，也就是说，GIF图像中的各个像素，要么就彻底不透明，要么就彻地透明，而无法控制透明的程度。但是PNG格式的图像就支持alpha透明，可以控制各个像素的透明度，比如某个像素是30%透</p>
<p><img   style="float:left; padding:0 10px 10px 0 "  src='http://learning.artech.cn/wp-content/uploads/2009/04/transparent-bg.png' alt='transparent-bg.png' /></p>
<p>因此我们就来考虑一下，如何使用这个特性来实现具有自然过渡的纹理背景。很显然，我们必须要把“渐变色”和“纹理”这两件事分配到两个图像中，并使渐变色地图像使用alpha透明，这样就可以自然过渡了。具体来说，上面的div#inner的背景图像仅负责渐变色和alpha透明，下面的div#outer负责纹理图案。</p>
<p>因此，首先解决 div#inner 的背景图像，把设计图改成左图所示的样子，灰白小方格交替的部分代表透明背景，在Phostoshop和Fireforks中，都是这样的。上侧的切片图像，取红色虚线以上部分。</p>
<p>注意，在导出的时候，在Fireworks中要选择PNG格式，要注意一点，PNG格式有 8位、24位和32位三种，由于这个图像中存在渐变色，8位格式产生的效果太差，无法使用，此外，24位的无法产生alpha透明，因此，这里选择32位的PNG格式导出（32位：24位=4字节：3字节，多出来的一个字节就是就是记录透明度的）。</p>
<p><img   style="float:right; padding:0 0 10px 10px"  src='http://learning.artech.cn/wp-content/uploads/2009/04/demo-effect-4.png' alt='demo-effect-4.png' /></p>
<p>接下来，div#outer的背景简单一些了，把渐变层去掉，只保留纹理层，也不需要透明，直接到处即可。</p>
<p>这样，代码不需要调整，产生的效果就很完美了，在IE7、IE8和Firefox中，都可以如图所示显示。</p>
<p><a  target="_blank" href="http://learning.artech.cn/20080213.css-exploring-published.html"><img   style="float:left; padding:0 10px 10px 0 "  src='http://learning.artech.cn/uploads/blog-files/css-cover-micro.jpg' alt='CSS 设计彻底研究' /></a></p>
<p>由于 IE 6 尽管支持PNG格式的图像，但是不支持PNG的Alpha属性，因此上面的页面在IE6中，不能正确先显示。要在IE6种也可以正常显示，需要借助于IE6 的 AlphaImageLoader滤镜，也同样可实现，这篇文章已经太长了，这里就不再详细介绍这个细节了，读者可以参考<a  target="_blank" href="http://learning.artech.cn/20080213.css-exploring-published.html">《CSS设计彻底研究》</a>的129页“柔边阴影”效果在IE6中的实现方法。但是要注意，我自己实验的结果是 AlphaImageLoader滤镜只对32位PNG图支持alpha透明，8位的PNG不行。</p>
<p>再给大家一个把alpha透明使用得登峰造极的例子：<a target="_blank" href="http://learning.artech.cn/20080314.break-down-css-zen-garden-ocean.html">《你问我答(21)——破解Kai Laborenz的神秘海底世界》</a>，这个例子是一个德国人做的CSS禅意花园的例子，太酷了。</p>
<p>如果你对“CSS滑动门技术”还比较陌生：</p>
<p>1：看一下这篇文章，<a target="_blank" href=" http://learning.artech.cn/20071105.css-slide-door-application.html">你问我答(11)——CSS滑动门技术的简单应用</a> 。</p>
<p>2：滑动门技术非常有用，<a  target="_blank" href="http://learning.artech.cn/20080213.css-exploring-published.html">《CSS设计彻底研究》</a>书里面在很多案例中用到了滑动门技术，表面上看起来完全不同的案例，实际上具有相同的技术本质，很有趣，有兴趣的读者可以看一看。</p>
<p>最后给出这个例子的源文件，<a href="http://learning.artech.cn/wp-content/uploads/2009/04/slide-door-demo.rar">感兴趣的读者可以点击这里下载</a>。</p>
<h3>思考题</h3>
<p>1：使用CSS布局，最核心的思想是什么？</p>
<p>2：你能否列举出一些你使用过的CSS滑动门技术的应用案例？</p>
<p>3：你是否能举出一些例子，说明“表面上看起来完全不同，本质上却是相同的”这个道理。</p>
<p>===============================================</p>
<p>[补充说明]</p>
<p>这篇文章贴出来一天之后，我发现我的解决方案还是有些问题的，虽然这个方法可以解决文中所说的读者问题中给出的图的要求，但是我给出的最后一个结果图，实际上和中间我画了一个红色方框的那个图相比，二者并不完全等价。区别在于，前者是在一个渐变色的基础上增加了纹理，后者在固定色上增加纹理后，又覆盖了一层渐变色，这两个效果是不一样的。因此用这种方法能够实现的效果，对设计效果时的操作步骤和顺序是有一定要求的，符合后者操作顺序的才能够拆到两个图像中，再叠加产生最终的效果。文章顶端的那个黑色图，是可以用这种方法做到的，因为渐变色是整个压在纹理上面的，而不是纹理压着渐变色。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090423.slide-door-application.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>网页设计杂谈(16)——CSS设计中的 Sprite 技术</title>
		<link>http://learning.artech.cn/20090421.css-sprite.html</link>
		<comments>http://learning.artech.cn/20090421.css-sprite.html#comments</comments>
		<pubDate>Tue, 21 Apr 2009 01:00:55 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[网页设计杂谈]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090421.css-sprite.html</guid>
		<description><![CDATA[如何在CSS中使用图像，是令不少初学者琢磨不定的问题，往往会使人感到有些迷茫。
今天专门就这个问题来谈一谈CSS Sprite技术，这是个非常实用的技术，在我们的几本CSS书籍中，都没有深入介... ]]></description>
			<content:encoded><![CDATA[<p>如何在CSS中使用图像，是令不少初学者琢磨不定的问题，往往会使人感到有些迷茫。</p>
<p>今天专门就这个问题来谈一谈CSS Sprite技术，这是个非常实用的技术，在我们的几本CSS书籍中，都没有深入介绍。今天算是做个补充。</p>
<h3>从十年前说起</h3>
<p>十年前，网页设计开始逐渐成为一项应用比较比较广的技术，那时制作网页就开始“切图”了。之所以要切图，主要有两个目的：</p>
<p>1：为了使用表格布局，就要把图像切成一个个小部分，分别放到表格中各自的单元格里面。</p>
<p>2：这样做可以使网页打开和显示速度更快。这是为什么呢？原因是，那时候人们主要还是通过33.6K或者54K的电话线拨号上网，速度非常慢，比现在主流的上网速度慢10到40倍，所以把一个比较大的图像分成若干块，这样浏览器在显示的时候 ，就会同时开多个线程，同时下载各个小块，这样可以更充分地利用带宽，其实原理就和“FlashGet快车”等下载软件是一个道理。</p>
<h3>十年后又如何？</h3>
<p>当今世界上没有什么技术的发展速度，可以和IT技术相比的。十年后的今天，情况已经发生了很大的变化，很重要的一点是上网的速度快了很多，虽然我们还不能和发达国家（甚至我们不甚看得上的韩国）动辄上百兆的入户带宽相比，但是好歹1-2兆的ADSL还是很普及的。当下载速度快了以后，我们考虑的侧重点就不一样了。</p>
<p>1：当浏览器显示一个图像时，所花费的时间实际上由两个部分组成的，通俗来说是“发出请求建立连接的时间”以及“传输图像数据”的时间。在网速很低的时代，前者时间与后者相比可以忽略不计，而当宽带上网以后，后者的时间大幅度的降低了，而前者并没有明显降低，因此前者所占的比例就不能忽略不计了。</p>
<p>2：一个网页上往往需要很多边边角角的很多小图象，比如按钮、圆角、边框等等，这写图像通常本身的大小都非常小，因此他们的传输时间都非常短，反而建立连接的时间无论图像大小，都是一样的，因此“建立连接”花去了整个下载时间中的较大比例。</p>
<p>3：因此，人们就想到了一个方法，把这些小图像都平放在一个大图像中，这样当显示页面的时候，一次就把他们都下载下来了，然后通过CSS仅仅把需要的部分显示在需要的位置，本质上的原理就是“<font color="#CC0000">通过减少HTTP请求的次数，达到加快网页打开的速度的目的。</font>”</p>
<p>4：<img style="float:right; border:1px #BBB solid ;padding: 3px;  margin:10px;" src='http://learning.artech.cn/wp-content/uploads/2009/04/super-mario.jpg' alt='css-sprite' />读者可能要问，“Sprite”是什么意思？这个技术为什么要叫这个名字呢？说到这里，就要再往前推若干年啦，想当年，如果你玩过任天堂的红白机，肯定会知道超级马力、魂斗罗之类的经典游戏，90后的新生代朋友估计就未必知道了，我们这个年纪的人应该是没有人不知道的，总之就是那种很古老的接在电视上的游戏了。而“Sprite”就是这些游戏程序开发中的一个很重要的技术，就拿超级马力来说吧，超级马力这个人物、他要吃的蘑菇、花、金币、要顶的砖块、要躲避的小怪物、乌龟等等游戏中的各种元素，都是事先做好的一些图像元素，这些元素的大小都是固定的，然后整个游戏就是把这些元素拼接在画面中形成的。而所有这些基本的图像元素就叫做Sprite——“精灵”。</p>
<p>5：和上面说的当年开发游戏中的Sprite很类似，如果我们把需要显示在页面中的多个图像放到一个图像中，一次性下载到浏览器，然后再分别显示到需要的地方，拼接成最终的效果，因此就使用了Sprite这个名词了。</p>
<h3>案例说明</h3>
<p>下面通过从小到大的几个例子，说明下Sprite技术是如何应用在实际工作中的。</p>
<h4>实际案例1：</h4>
<p><a target="_blank" href="http://learning.artech.cn/20080213.css-exploring-published.html"><img  style="float:right; margin:3px;" src="http://learning.artech.cn/uploads/blog-files/css-cover-micro.jpg" alt="CSS设计彻底研究" /></a>在<a target="_blank" href="http://learning.artech.cn/20080213.css-exploring-published.html">《CSS设计彻底研究》</a>这本书里，我们虽然没有给出CSS Sprite这个名称，但实际上也介绍了使用的方法，192页，8.4节“三状态玻璃效果菜单”这个案例中，我们就是把三种状态的背景图像都放在了一个图像文件中，并提到了这样做的两个优点：</p>
<p>1：减少了文件的数量，便于网站的维护管理。</p>
<p>2：鼠标指针移动到某个菜单项上，如果要更换一个背景图像文件，那么有可能要替换的图像还没有下载下来，就会出现一个停顿，浏览者会不知发生了什么，而如果使用同一个文件，就不会出现这个问题了。</p>
<p>这个完整案例比较复杂，这里应用的CSS Sprite只是整个例子中很小的一部分，这里就不再详细介绍了。下面针对Sprite举一个实际的案例。</p>
<p><img style="float:right;  border:1px #BBB solid ;padding: 3px;  margin:10px 0 10px 10px"  src="http://learning.artech.cn/wp-content/themes/mesozoic/images/side-title.png" alt="CSS sprite" width="80" height="170" /><br />
<h4>实际案例2：</h4>
<p>其实我们这个网站的页面右侧栏中，就用到了Sprite技术。如果您使用Firefox浏览器浏览本页面，用鼠标右键单击右侧栏的每个圆角框中的四字标题，比如“视频教程”这4个字，然后在弹出菜单中选择“查看背景图像”，你将会看到如右图所示的这个图像。</p>
<p>可以看到，我们把若干个项目的标题都放在了一幅图像中。在对应的CSS中，比如“视频教程”这4个字所在的元素是一个span，它的CSS代码如下，文件style.css 第 803 行：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="css"><span style="color: #cc00cc;">#sidebar</span> ul li h2 span<span style="color: #6666ff;">.category</span> 
<span style="color: #66cc66;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">background</span>: <span style="color: #993333;">url</span><span style="color: #66cc66;">&#40;</span><span style="color: #933;">images/side-title<span style="color: #6666ff;">.png</span></span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333;">no-repeat</span> <span style="color: #933;">0</span> -<span style="color: #933;">40px</span>;
    display<span style="color: #3333ff;">:block</span>; 
    height<span style="color: #3333ff;">:<span style="color: #933;">20px</span></span>;
    width<span style="color: #3333ff;">:<span style="color: #933;">200px</span></span>;
<span style="color: #66cc66;">&#125;</span></pre></td></tr></table></div>

<p>可以看到，这个图像作为span元素的背景，span元素设置为块级元素（相当于div），并设置高度和宽度，在background属性中，设置了图像的路径，以及位置，关键在于这里的-40px，表示向上移动40像素，这时在高20px、宽200px这个“窗口”中显示的就正好是“视频教程”这一行了。其他各标题，以此类推，只要修改这个竖直方向的数值即可了。</p>
<p>这个小例子非常简单，相信只要有一点点CSS基础的读者都可以一眼就看明白。如果对上面这几行代码还不清楚的读者，可以看一下右侧“视频教程”目录下的教程，相信就会理解了。</p>
<p>下面我们看看一些大网站是怎么用这个技术的。</p>
<h4>Apple公司网站</h4>
<p>苹果公司是彻底靠设计吃饭的公司，我们先来看看苹果公司网站的菜单是如何实现的，请进入苹果公司的网站： <a target="_blank" href="http://www.apple.com.cn">www.apple.com.cn </a>，然后使用上面相同的方法，查看背景图像，可以开到结果如下所示。<a target="_blank" href="http://www.apple.com.cn/global/nav/images/globalnavbg.png">或直接察看源文件</a>，也许以后苹果公司网站会改版，这个图像可能会变化。</p>
<p><center><a target="_blank" href=http://www.apple.com.cn/global/nav/images/globalnavbg.png' title='apple.com-sprite'><img src='http://learning.artech.cn/wp-content/uploads/2009/04/apple-menu.jpg' alt='apple-menu' /></a></center></p>
<p>原来是把菜单的不同鼠标状态都做到了一幅图中，再根据不同的页面，以及不同的鼠标状态，通过CSS在各个菜单项对应的“小窗口”中透出需要的那一小块。</p>
<h4>淘宝网</h4>
<p>淘宝网站的设计是很重视用户体验的，也是不少设计师向往去工作的公司。我们来看看淘宝是否使用了Sprite技术，结果如下图所示，<a target="_blank" href='http://assets.taobaocdn.com/app/fp/2009/hd_20090313.png' title='taobao-sprite'>点击查看源文件</a>。</p>
<p><center><a target="_blank" href='http://assets.taobaocdn.com/app/fp/2009/hd_20090313.png' title='taobao-sprite'><img width="400" style="border:1px #BBB solid;padding:3px;" src='http://learning.artech.cn/wp-content/uploads/2009/04/taobao-sprite.png' alt='taobao-sprite' /></a></center></p>
<p>可以看到，同样，也把页面上的很多边边角角的设计元素都做到一张图上，然后再拼成所需要的显示效果。</p>
<h3>思考题</h3>
<p>1：Sprite技术的核心原理是什么？你能否将淘宝中Sprite图的各个“零件”与最终页面中出现的位置和元素对应起来？</p>
<p>2：从Sprite这个技术来由，你能否体会到“新技术”和“老技术”之间的关系？对你学习新技术有什么启示吗？</p>
<p>3：自己动手，查看一下其它还有那些大网站使用了类似的技术，163.com、yahoo.com、amazon.com 。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090421.css-sprite.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Web开发杂谈(1) —— 学习开发的三个层次</title>
		<link>http://learning.artech.cn/20090418.how-to-learn-web-dev.html</link>
		<comments>http://learning.artech.cn/20090418.how-to-learn-web-dev.html#comments</comments>
		<pubDate>Sat, 18 Apr 2009 04:41:03 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[Web开发杂谈]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090418.how-to-learn-web-dev.html</guid>
		<description><![CDATA[由于我们现在的内容已经不仅仅在Web设计这个领域上了，所以新开一个新的系列——“Web开发杂谈”，讨论开发相关的话题。
有不少读者和网友经常地留言，问类似这样问题：“我没有相关基... ]]></description>
			<content:encoded><![CDATA[<p>由于我们现在的内容已经不仅仅在Web设计这个领域上了，所以新开一个新的系列——“Web开发杂谈”，讨论开发相关的话题。</p>
<p>有不少读者和网友经常地留言，问类似这样问题：<font color="#AA0000">“我没有相关基础，我应该学习什么课程？”</font>，或者<font color="#AA0000">“我没有相关基础，我能学会某某技术吗？”</font>，<font color="#AA0000">“我不是计算机专业的，我能学会编程吗？”</font>。</p>
<p>作为这个系列的第一篇文章，就来谈谈我个人的一些想法，回答这个问题，和读者分享一下。</p>
<h3>一、概述</h3>
<p>就像刘欢可以算是咱们中国顶尖的男歌手了吧，他可是没上过任何音乐院校。所以上不上大学，以及上什么专业，都不是关键的问题。<font color="#AA0000">但是绝不是说，你什么都不学，就可以做技术开发工作</font>。</p>
<p>我要说的是：如果打算做开发工作挣钱养活自己，可以什么学都不上，但是<font color="#AA0000">该学的东西都得学，一样也不能少，捷径是没有的，想绕过基础课，直接学习所谓“有用”的东西，是不可能的</font>。</p>
<p>首先，任何技术工作都是需要一些基础的，获取这些基础知识和能力的最通常的方法，是上大学的相关专业。但是中国的教育现状，使得上大学和寻找自己的兴趣，这两件事往往无法统一，所以出现了很多学非所用，和用非所学的情况，这是很无奈的事情。但是需要指出的一点就是，无论要做什么，都是需要一些必须的基础知识，或者说，更重要的是一些基本的思想方法的。</p>
<p>各个职业之间所需要的思想方法和技能是不同的，因此，如果你希望进入一行，就应该先踏下心来，把这一行所需要的基本知识和思想方法掌握，无论你在大学是不是计算机专业，如果想做这一行，就应该（必须）把一些基本的课程掌握。</p>
<p>现在的一个现实情况是，很多朋友希望学习一两本书，就能作很大的事情，能做很牛的事情，这个是不现实的，任何知识和技能体系的建立都是一个综合、按部就班的过程。你要相信一点，大学四年的课程一定不是在浪费时间。除非对于确实天才的人来说，有可能是浪费时间，比如对于比尔盖茨这样的人，不过我相信如果您是这样的人，一定不会在阅读我写的这篇文章了：）</p>
<p>那么，到底应该学一些什么东西呢？那么从我的理解来说，应该有一个比较长远的学习计划，逐步提高。这个计划应该包括三个层次的内容：</p>
<h3>第一个层次：大学计算机专业的基础课</h3>
<p>这个层次的主要目标，是真正理解计算机内部是怎样运行的，你应该能在200字内，用自己的语言说清计算机的原理，应该理解什么叫寄存器、运算器、存储器？什么叫队列、栈、堆？什么叫递归、迭代？什么叫算法时间复杂度、空间复杂度？什么叫进程、分时、调度？什么叫文法、正则表达式？什么叫数据库设计的范式？什么叫关系、函数、群？</p>
<p>这些东西都不是直接用在你的开发中，但是没有这些基础，你永远无法真正理解什么叫程序。</p>
<p>在以后的文章里，我可以对大学计算机专业比较重要的一些课程，做一些简单的介绍，讲一讲它们的基本内容和特点。事实上我最近从网上找了几所大学的教学大纲，基本上和我十几年前学的课程没有什么变化，这也说明了，这些基础课的重要性和稳定性。</p>
<h3>第二个层次：开发必备的工具</h3>
<p>在有了上述基础，真正做开发还需要掌握一些主流的开发工具，实际上一个项目需要涉及很多方面，需要用到很多工具，比如说下面是某个网站项目用到的开发工具栈：</p>
<ul style="text-indent:0px;">
<li>框架平台： Microsoft ASP.NET 3.5 SP1</li>
<li>语言： C#</li>
<li>开发环境： Visual Studio 2008 Team Suite</li>
<li>Web框架： ASP.NET MVC</li>
<li>客户端框架： JQuery</li>
<li>数据库：SQL Server 2008</li>
<li>数据访问层框架： LINQ to SQL</li>
<li>源码控制： Subversion</li>
<li>源码控制集成：  VisualSVN 1.5</li>
</ul>
<p>上面的开发工具栈是以.NET平台为例的，目前Web开发的主流“三巨头”（.NET、JAVA、PHP），都各自有一套比较完整的开发工具栈，上表中各个项目也都有个各自的工具，比如上面.NET项目用的是C#语言，对应JAVA平台就是JAVA语言；.NET用Visual Studio作为集成开发环境，JAVA则可以使用Eclipse；上面用的Web框架是ASP.NET MVC，JAVA对应的则是Struts；上面项目用的ORM是 LINQ to SQL，而JAVA则有Hibernate对应，等等。</p>
<p>因此，所有开发人员学习的第一个层次课程都是相同的，而第二个层次的内容，则需要先做一个选择，你打算走哪条路线，实际上“三巨头”（.NET、JAVA、PHP）都可以，至少在几年内，都会是主流技术。但是要注意的两点是：</p>
<p>1：选择某一个路线以后，所有相关的工具就都要选配套的了。这就好像玩单反相机的兄弟，一但选择了尼康还是佳能的机身，那么以后很长时间里，你再配各种镜头、配件，就都得跟着机身走了。而且一旦用习惯了，再换就麻烦了，而且你以前积累的所有镜头都不能用了，很麻烦。当然，要换或者同时拥有多家的也是可以的。</p>
<p>2：在摄影社区里，N（尼康）C（佳能）粉丝之间的“口水战”是永远的话题，同样在开发社区里（.NET、JAVA、PHP）的口水大战也是年复一年、日复一日的。其实这是完全没必要的，如果尼康和佳能之间的质量差异能够让普通人都看出来，那早就有一家倒闭了。实际上在“寡头垄断”的行业里，寡头之间的差异是极小的，否则就不会是一个稳定的状态了。如果你学过物理学就知道，这是热力学第二定律“熵增加原理”早就说明了的道理。我们这些普通人，根本不必为这些事儿操心，你就踏踏实实选一个你喜欢的，看着顺眼的，用着顺手的，走下去就可以了。</p>
<h3>第三个层次：提高程序质量的修炼</h3>
<p>如果基础的原理你都理解了，上面列的一些工具也都掌握了，基本上也应该是一个职业的开发人员了，那么你的目标应该不是仅仅做一个合格的程序员，而应该是做一名优秀的程序员。评价一个人工作是否优秀，标准就是看他的产品质量如何。对于程序员来说，他的产品就是它写出来的程序代码，因此，就要看他的程序质量如何。</p>
<p>在这方面，就有很多方面要不断地修炼，而这种修炼都是长期的，潜移默化地进行着。从方法来说，无非几个：</p>
<ul style="text-indent:0px;">
<li>加入一个好的团队，跟着学，比自己摸索当然快得多。</li>
<li>勤于动脑，肯与思考，不爱动脑子的人做什么都不可能成功。</li>
<li>平常多留心，经常上网学习，网络时代，不会利用这个工具，就等于放着洋枪洋炮不用，非用大刀长矛。</li>
<li>善于总结，把一些临时突发的心得体会，变成经过思考的原则，以指导实践。</li>
<li>写一些技术博客文章，这个过程既是对自己的总结提高，还可以帮助别人，一举两得。</li>
</ul>
<p>从具体方面来说，比如如下几点：</p>
<ul style="text-indent:0px;">
<li>设计模式的掌握，对于提高代码结构的质量很重要，这也是能否从小兵成成长为指挥员的很重要一步。</li>
<li>随着承担的程序规模越来越大，对测试等相关方面的要求会越来越高。</li>
<li>对算法的理解，这是个博大精深的方面，值得永远不懈努力。</li>
<li>对于直觉的培养，随着经验的积累，要不断提高自己直觉的能力，因为要做出超越别人的东西，依靠的不是常规的思维，而是灵感和直觉。</li>
<li>培养快速学习能力，一本大学教材，看三天应该能掌握60%的基本思想方法和内容，而且能迅速找出实际工作需要的部分，并深入理解。</li>
<li>总之，既要重视日久天长的长期修炼，也要重视应急的快速反应能力。都是很重要的。</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090418.how-to-learn-web-dev.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>近几天电信接入用户访问本站速度较慢</title>
		<link>http://learning.artech.cn/20090412.network-problem.html</link>
		<comments>http://learning.artech.cn/20090412.network-problem.html#comments</comments>
		<pubDate>Sun, 12 Apr 2009 08:08:16 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[本站信息]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090412.network-problem.html</guid>
		<description><![CDATA[最近若干天来，有不少来自南方城市的电信用户反映，我们的网站访问速度变慢。同时一些在南方的&#8221;学以致用&#8221;计划的一些会员朋友，也反映了这个问题。我们请国内不同地方的朋友协... ]]></description>
			<content:encoded><![CDATA[<p>最近若干天来，有不少来自南方城市的电信用户反映，我们的网站访问速度变慢。同时一些在南方的&#8221;学以致用&#8221;计划的一些会员朋友，也反映了这个问题。我们请国内不同地方的朋友协助，使用tracert的结果来看，主机访问速度下降的原因，应该是电信骨干网线路的问题。目前出现问题的用户主要集中在南方电信的用户。</p>
<p>从各地网友反映的情况来看，我们估计是电信的骨干网在进行升级或者调整，这种情况可能要持续几天。首先，希望这个问题仅仅是技术问题，而没有其他非技术因素在里面；其次，希望中国电信的大人们能加油工作，早日恢复正常访问。这里是我在网上找到的一位 <a target="_blank" href="http://www.cbmland.com/post/845/limited-hosting-abroad.html">网友发的一个帖子</a>，也说明了这个问题。</p>
<p>目前北方城市没有明显的变化，我们自己使用的北京网通ADSL速度还可以，虽然和去年奥运前后的速度相比慢了一些。</p>
<p>读者有相关信息，可以在这里留言，谢谢！</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090412.network-problem.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>代友发招聘启事</title>
		<link>http://learning.artech.cn/20090410.job-opportunity.html</link>
		<comments>http://learning.artech.cn/20090410.job-opportunity.html#comments</comments>
		<pubDate>Fri, 10 Apr 2009 06:13:58 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[本站信息]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090410.job-opportunity.html</guid>
		<description><![CDATA[在这里代一位朋友发一则招聘启事，地点在北京，有兴趣的读者可以考虑，请直接将简历发送到下面列出的电子邮件地址。
===以下是朋友写的招聘要求==========================
Ad net 是一家世界领先... ]]></description>
			<content:encoded><![CDATA[<p>在这里代一位朋友发一则招聘启事，地点在北京，有兴趣的读者可以考虑，请直接将简历发送到下面列出的电子邮件地址。</p>
<p>===以下是朋友写的招聘要求==========================</p>
<p>Ad net 是一家世界领先的数字媒体和网络技术公司、公司位于北京海淀高新技术开发区，是由业界资深的管理团队、资深的通信技术和互联网技术专家创立。核心管理人员和技术人员来自美国硅谷和国内知名的通信公司，均具有十年以上的业务管理和技术研发经验。公司开发的网吧影视服务平台（http://eyoo.o8cafe.com）是一套代表当前技术最高水平的、端对端的，进行媒体内容的收集、发行和管理的系统平台。通过此平台，用户可通过互联网、无线蜂窝网络和宽带获得这些媒体内容。应公司发展要求，公司诚聘.net 软件开发工程师一名。</p>
<p>1、熟悉W3C标准及规范，熟练掌握HTML/XHTML、Div、CSS、Javascript等Web页面技术；<br />
2、有一定的美工基础，能够使用工具进行页面切片。<br />
3、了解AJAX技术应用开发，掌握Jquery库。<br />
4、熟悉C#、.NET Framework体系，能够独立进行B/S结构软件开发<br />
5、熟悉MS SQL Server数据库的设计与开发者<br />
6、熟悉网站部署和维护者<br />
7、有良好的沟通与团队合作精神，能适应较大的工作压力。 </p>
<p>有意请发个人简历至：<br />
zpan@admedianet.com</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090410.job-opportunity.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>昨天网站暂停半天及相关事宜</title>
		<link>http://learning.artech.cn/20090410.thinking-on-site-load.html</link>
		<comments>http://learning.artech.cn/20090410.thinking-on-site-load.html#comments</comments>
		<pubDate>Fri, 10 Apr 2009 03:26:34 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[本站信息]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090410.thinking-on-site-load.html</guid>
		<description><![CDATA[昨天下午收到了虚拟主机提供商发来的邮件，告知由于我们的网站负载过大，被暂停了。由于当时在外面，无法及时处理，晚上经过接洽，并对网站做了适当的处理，才得以恢复。而在这个过... ]]></description>
			<content:encoded><![CDATA[<p>昨天下午收到了虚拟主机提供商发来的邮件，告知由于我们的网站负载过大，被暂停了。由于当时在外面，无法及时处理，晚上经过接洽，并对网站做了适当的处理，才得以恢复。而在这个过程中，我有一些想法和收获，在这里和大家分享一下。</p>
<p>一、虚拟主机的负载能力</p>
<p>所谓虚拟主机，就是提供商在一台服务器上为众多的客户（网站）提供服务，这些客户的网站共享这一台服务器的所有资源，包括：硬盘空间、内存、CPU和带宽等等。国外的主机提供商在一台服务器上可以放置多达多千个网站。这样，每个客户需要支付的费用经过这样平摊，就变得很低了。</p>
<p>因此，每个网站都不能使用太多的资源，我们现在这个虚拟主机的要求是：服务器上的每个帐号（客户）不能在连续的2分钟内，占用CPU超过25%，如果超过则会暂停网站。在邮件中，列出了当时我们的网站的资源占用情况，在那一个时刻，我们的网站占用了79%的CPU资源。对于我们的网站，CPU资源主要是花费在PHP动态页面上，这79%的资源主要是在同一时刻，有12个php文件被同时访问造成的。注意，这里的“12”的含义不是通常所说的“在线人数”的含义，“在线人数”一般是说在一定时间内，比如15分钟内，访问过的IP数；而这里说的12是操作系统意义上的“并发访问”，是一个瞬间的含义。因此“在线人数”要远远大于“并发访问”数量。</p>
<p>实际上，虚拟主机的质量是很难简单评估的，因为第一：他们不会公布一台服务器上到底会放置多少网站，第二：也不见得放置得少，效果就好。</p>
<p>二、虚拟主机商的服务质量</p>
<p>我们使用的是Hostgator的虚拟主机，我们对其提供的主机是非常满意的，主机稳定性非常好，而且服务非常到位。我们的流量每个月1000多G，这在国内的虚拟主机是很难想象的。更重要的是体现在服务上，这个具体很难量化说明，但是总体来说会感到非常舒服，比如，1：非常透明，这次停机以后，它会给出非常详细的列表说明当时的连接、进程以及CPU占用情况，2：并且他们会做出一定的分析，还给出了一个建议：由于我们的网站使用的是Wordpress系统，他们在邮件中建议使用WP Super Cache插件，我就安装了这个插件，感觉确实非常好，这样绝大多数访问，都由原来的访问动态PHP变为访问静态文件，这样对于CPU的占用，就大大降低了，而且访问速度也会加快。这也说明了一个真理——科技是第一生产力。根据这个插件的开发者的测试，这个插件可以在同样的负载情况下，支撑的访问量增加数倍。对于做网站来说，用尽量少的服务器资源，提供尽量大的支持访问能力，就是生产力，也就是钱哦。</p>
<p>三、令人头疼的下载问题</p>
<p>实际上我们的网站分为两部分，一部分是这个网站系统，即使用的Wordpress系统搭建的这个网站，这部分实际上不是构成负载的主要部分，负载主要是另一部分：提供的视频教程下载。下载是非常耗费资源的。如果不加任何限制，是不可想象的。更严重的问题在于很多人使用各种下载工具，这些下载工具都用同一个原理——多线程分块同时下载。也就是本来下载一个10M文件用一个连接，而这些软件会建立10个到服务器的连接，把这个文件分成10小块同时下载，夏在完成后再拼装成原来的文件。而且往往还会同时下载多个文件，这样，一个用户就会和服务器同时建立10X10=100个连接，这样的话，服务器当时的负担就变得超级大了。如果遇上同时有不止一个人这样做，肯定立即就会超过限制。而且，即使没有超过极限，这样做会使某一个人得到其他访问者100倍的资源，这样当然很不好。理想的状态应该尽可能使所有访问者平均地占用服务器资源。 因此，如果不使用一些限制，是肯定不行的。</p>
<p>四、目前我们使用的限制下载的措施</p>
<p>我们要做的，就是保证每一个访问的人，不要占用太多的连接，以致于影响其他访问者。实际上，如果使用独立的服务器，也就是我们的网站独自使用一台服务器的话，Apache上可以安装一个模块，就可以非常方便地限制每个IP的最大连接数，当超过这个连接数以后，直接拒绝掉超过的连接，这是非常适用于我们的情况的。但是遗憾的是，由于我们使用的是共享的主机，没有权限安装这个模块。那么怎么办呢？只能DIY一下了，自己写了一个PHP程序，来实现这个要求，当然只能部分实现了。</p>
<p>现在我对下载限制的是：</p>
<p>1：在同一个时刻，每个IP只允许有一个连接进行下载，比如说，一个用户正在下载或播放某一个视频教程，那么此时那就无法下载或播放其他视频教程。</p>
<p>这个要求用PHP是可以实现的，只需要把一个下载请求的IP记录在数据库中，对每次来的下载请求先在数据库中查一下，如果已经在下载文件了，那么就拒绝这个IP的请求，当一个下载结束或者人为终止以后，就在数据库中删除这个IP的记录，这是他在访问就被允许了。</p>
<p>但是仅仅这样做还不够，因为还会有很多人使用下载工具，大量并发地发出下载请求，而由于使用了上面第1条措施后，所有的下载请求都会转到一个PHP文件上，这样如果并发的下载请求数量很多的话，就需要服务器创建大量的PHP进程，这也是一个非常大的负担，而且Apache对于同时并发创建的PHP进程数量是有限制的。为此，我们就不得不采取第二个限制措施：</p>
<p>2：对于那些非常疯狂地发出并发下载请求的IP，就只能实施封锁的办法了。</p>
<p>我们经常会观察到一秒钟发出超过10个请求的IP，这些IP就必须要拒绝掉了。我们会记录每一个下载文件的IP在一段时间中发出的请求数量，如果超过一定限额，就封IP了，也就是这个“拒绝”命令直接由web服务器Apache发出，而不再由PHP程序发出。</p>
<p>目前，把疯狂发出下载请求的IP放入黑名单这个功能可以由这个程序自动实现。当然更理想的状态是经过一段时间比如1个小时以后，再自动从黑名单中去掉，这个我没有做到程序里。因此，指使人工地过一段时间把黑名单清空一次。我对PHP所知甚少，没有太多的时间把这个程序做得很复杂了。</p>
<p>当然在设置了上面的限制以后，对一些访问者是有麻烦的，比如在局域网中的不同的人，往往使用同一个对外的IP，这样他们就会被看作是同一个IP而加以限制。但是目前我们也只能这样了。</p>
<p>以后有条件的话，我们会尽可能改善服务期的条件，比如使用独立主机等等，但是还是需要一定的盈利以后，才可以做到。再不赢利的情况下，服务器的投资还无法做到很大。</p>
<p>如果哪位有一些更好的建议，可以告诉我们，谢谢大家两年多以来对前沿科技的支持！</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090410.thinking-on-site-load.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>你问我答(35)——破解缝隙之谜(续)</title>
		<link>http://learning.artech.cn/20090327.ie-6-text-node-bug.html</link>
		<comments>http://learning.artech.cn/20090327.ie-6-text-node-bug.html#comments</comments>
		<pubDate>Fri, 27 Mar 2009 12:18:48 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[你问我答]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090327.ie-6-text-node-bug.html</guid>
		<description><![CDATA[今天上午回答了一位读者的问题，有几位朋友在留言中给出了一些评论，其中 蓝月 网友给出了一个解决方法，使我想到了以前遇到的另一个问题，因此这里再补充，并更深入地扩展说明一下。... ]]></description>
			<content:encoded><![CDATA[<p>今天上午回答了一位读者的问题，有几位朋友在留言中给出了一些评论，其中 蓝月 网友给出了一个解决方法，使我想到了以前遇到的另一个问题，因此这里再补充，并更深入地扩展说明一下。</p>
<p>如果没有看过上一篇文章的读者，可以先看一下：<a target="_blank" href="http://learning.artech.cn/20090327.vertical-align-application.html">你问我答(34)——破解缝隙之谜</a></p>
<p>蓝月指出，如果在div标记和img标记的尖括号都连起来写，不加空格，就不会出现这个缝隙了。例如这样写（请注意img标记的尖括号的位置）：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre>        &lt;div style=&quot;border:1px solid #FF0000;&quot;&gt;
              &lt;img src=&quot;pic.jpg&quot; 
         &gt;&lt;/div&gt;</pre></td></tr></table></div>

<p>这里比较一下上面的写法和下面的写法有什么区别呢？</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre>       &lt;div style=&quot;border:1px solid #FF0000;＂&gt;
             &lt;img src=&quot;images/logo1.jpg&quot;&gt;
       &lt;/div&gt;</pre></td></tr></table></div>

<p>上面两种写法，再Firefox和IE 8中，是完全一样的，而在IE6和IE7种，却有所不同。</p>
<p>浏览器在解析HTML的时候，除了标记节点之外，还会根据需要生成文本节点。例如昨天的文章中，在图像的后面加了几个字母以后，就产生了一个文本节点，在没有字母的时候，本来是不应该产生文本节点的，但是IE在解析上面一种写法的代码时，会把标记之间的空格解释为文本节点，从而根据默认的规则，图像的底边和就会和文本的基线对齐，而产生了这样一条缝隙。</p>
<p>而当本来完全一样的代码，写成上面的第一种写法时，由于标记之间（尖括号之间）不加空格，因此IE6、IE7也不会解析出文本节点，从而也就不会产生这个缝隙了。这就解释了蓝月的方法为什么可以解决这个问题。</p>
<p>由此我又想到了另一个多次遇到过的针对IE6的问题，本质和这个问题是完全一样的，因此这里也介绍给大家。如下图所示的是一个很常用的效果，CSS的目的是将列表项目中的a元素改为块级元素，从而使得响应鼠标的范围扩展到li的矩形范围，而不仅仅是链接文字。</p>
<p><center><img src='http://learning.artech.cn/wp-content/uploads/2009/03/ie-li-preview.png' alt='ie-li-preview.png' /></center></p>
<p>代码很简单，如下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre>&lt;style&gt;
    li a {
        display:block;
        background:#CCC;
        border-bottom:1px #000 solid;
        text-decoration:none;
    }
    li a:hover {
        background:#BBB;
    }
&lt;/style&gt;
&nbsp;
&lt;body&gt;
    &lt;ul&gt;
         &lt;li&gt;&lt;a href=&quot;#&quot;&gt;First Item&lt;/a&gt;&lt;/li&gt;
         &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Second Item&lt;/a&gt;&lt;/li&gt;
         &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Third One!&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/body&gt;</pre></td></tr></table></div>

<p>事实上，以上代码在IE7、IE8、Firefox这些浏览器中都没有问题，但是在IE6中，效果将如下图所示：</p>
<p><center><img src='http://learning.artech.cn/wp-content/uploads/2009/03/ff-li-preview.png' alt='ff-li-preview.png' /></center></p>
<p>在各个li之间为什么会产生这个缝隙呢？其实原理和上面谈到的原意是一样的，IE 6 在某些时候，会把标记尖括号之间的空格解释位文本节点，因此，解决方法就是把HTML代码的换一种写法：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre>    &lt;ul&gt;
         &lt;li&gt;&lt;a href=&quot;#&quot;&gt;First Item&lt;/a&gt;&lt;/li
         &gt;&lt;li&gt;&lt;a href=&quot;#&quot;&gt;Second Item&lt;/a&gt;&lt;/li
         &gt;&lt;li&gt;&lt;a href=&quot;#&quot;&gt;Third One!&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;</pre></td></tr></table></div>

<p>可以看到，我们仅仅把</li>
<p>分在两行里写，以保证消除标记之间的空格，在IE 6中效果就立即正常了，如下图所示。</p>
<p><center><img src='http://learning.artech.cn/wp-content/uploads/2009/03/fixed-li-preview.png' alt='fixed-li-preview.png' /></center></p>
<p>需要说明的是，通过这种HTML格式的方式解决这个问题，未必是看起来最舒服的一种，当然通过CSS来解决也是可以的。不过这种方式的最大优点就是快捷和直接，立竿见影，哪里多出了文本节点，就直接在HTML中消灭掉他。如果用CSS来解决则需要具体问题具体分析，会稍微麻烦一些，当然也是完全可行的。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090327.ie-6-text-node-bug.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>你问我答(34)——破解缝隙之谜</title>
		<link>http://learning.artech.cn/20090327.vertical-align-application.html</link>
		<comments>http://learning.artech.cn/20090327.vertical-align-application.html#comments</comments>
		<pubDate>Fri, 27 Mar 2009 01:34:00 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[你问我答]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090327.vertical-align-application.html</guid>
		<description><![CDATA[今天收到一位读者的问题，比较有趣，这里介绍给其他读者分享。首先这位读者在前几天的留言中问了这样一个问题：
“您好! 请问，将图片放于Div标签中时,底部与右部都会出现间隙，请问如... ]]></description>
			<content:encoded><![CDATA[<p>今天收到一位读者的问题，比较有趣，这里介绍给其他读者分享。首先这位读者在前几天的留言中问了这样一个问题：</p>
<p><font color="#AA0000">“您好! 请问，将图片放于Div标签中时,底部与右部都会出现间隙，请问如何去除？”</font></p>
<p>这个问题问得很笼统，我也很难具体帮助他，因此只能给出一些指导性的原则，因此我这样回答了他：</p>
<p><font color="#AA0000"></p>
<p>“这个需要具体调试，看一看这个间隙到底什么原因造成的。关于调试，可以参考一下这篇文章:</p>
<p><a target="_blank" href="http://learning.artech.cn/20080129.css-debug-skills.html">http://learning.artech.cn/20080129.css-debug-skills.html</a> ”</font></p>
<p>我猜想，这位朋友很认真地看了这篇文章，做出了努力，然后给我回信如下：</p>
<p><font color="#AA0000">&#8220;感谢您的回复，经过您的指点，发现了问题的所在，但是问题依然没有解决。询问几个老师，都无法解决（已经ff，及ie测试）。闻前沿工作室的老师对此造诣颇深，烦请赐教！！！现附代码及效果图如下：&#8221;</font></p>
<p>代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre>&lt;body&gt;
        &lt;div style=&quot;border:1px solid #FF0000;&quot;&gt;
              &lt;img src=&quot;images/logo1.jpg&quot;&gt;
        &lt;/div&gt;
&lt;/body&gt;</pre></td></tr></table></div>

<p>效果：</p>
<p><center><img src='http://learning.artech.cn/wp-content/uploads/2009/03/ie-6-preview.png' alt='ie-css-bug' /></center></p>
<p>可以明显地看到图片和下边框之间出现了一条缝隙。而右侧的缝隙我想这位读者不应该有什么疑问，因为div是个块级元素，自然会有右伸展到右端，我觉得这个不是读者要问的问题。而这个关键的问题是底下的这条缝隙到底是怎么产生的呢？以及如何去掉这个缝隙呢？</p>
<p>下面我来解答一下这个问题。</p>
<p>首先要说说的是，这位读者是一个很善于学习的读者，从第一次提的问题，到第二次提的问题，可以发现，第一次的问题，别人很难了解他遇到的到底是什么问题，而第二次的问题，他做了三件事：</p>
<p>1：简化代码，暴露问题，得到了<font color="#FF0000">一段出现问题的最简代码</font>，2：给出了这段非常简单的代码，3：给出了问题的效果图。 </p>
<p>这样我们就可以一眼知道问题是什么了。这样对于提问者来说，就非常容易得到别人的帮助，比如你到某个论坛去发帖寻求帮助，如果做到了上面这三点，别人就很容易能帮上你，而如果仅仅是一句话的描述，或者是把非常大的一段代码贴上去，别人就很难帮上你了。具体“提问的艺术”请参考：<a target="_blank" href="http://talking.artech.cn/thread-178-1-1.html">http://talking.artech.cn/thread-178-1-1.html</a> 。</p>
<p>下面具体说一说这个缝隙到底是怎么来的。</p>
<h4>第一步：摸底</h4>
<p>假设现在我们遇到这个现象，不知道是什么原因，首先用各种浏览器都看一看，分别效果如何。也就是先摸摸底。当我们使用 Firefox 、IE 6 、IE 7 、IE 8 观察以后，可以发现，这个缝隙在IE 6和IE 7中都是存在的，而在Firefox和IE 8中去不存在，看来IE 8还是不错的。</p>
<p><center><img src='http://learning.artech.cn/wp-content/uploads/2009/03/ie-8-preview.png' alt='ie-8-preview' /></center></p>
<p>btw，关于如何方便地使用多种IE浏览器查看一个网页，可以参见：<a href="http://learning.artech.cn/20090316.ie-tester-recommendation.html">《CSS调试工具推荐 —— IE Tester》</a></p>
<p>这里有一个经验之谈，如果在IE6和IE7中的效果不一样，而IE7和Firefox中效果相同，通常是IE6的bug，而如果IE6和IE7中的相同，而与Firefox不同，通常是他们对CSS标准的解释不同。</p>
<p>OK，读到这里，如果您以前没有遇到过这个问题，不妨先停下来，自己试试看，能不能快速地找到这个缝隙的产生原因。如果5分钟内搞定，可以认为自己的CSS基础知识过关啦~~~</p>
<h4>第二步：尝试</h4>
<p>此前我也没有遇到过这个问题，所以这里就要来点头脑风暴了，就像初中证明平面几何题，有时候是要靠点运气和灵感的。就好像在证明几何题中添加“辅助线”往往是最关键的一步，这里我们可以试试看在图片后面加几个字母，就相当于添加一条辅助线，看看效果如何。</p>
<p><center><img src='http://learning.artech.cn/wp-content/uploads/2009/03/ie-6-preview-2.png' alt='add-some-text' /></center></p>
<p>看了上图，这下子就有线索了，请读者仔细看一下，一共六个字母，左右各三个，你发现各自的特点了吗？——右边的三个的下端都带有一个“钩”，而左边的三个没有。到这里我们已经明显地感觉到问题很可能和它旁边的文字有关，因为这个缝隙的高度和这个“钩”的高度很一致。辅助线起作用了！</p>
<h4>第三步：联想</h4>
<p>我们这时联想一下文字和图像相关的内容，自然可以联想到“图片与文字的对齐方式”这个问题了，如果读者手边有“<a target="_blank" href="http://www.amazon.cn/mn/detailApp?prodid=zjbk586224&#038;source=artech">HTML+CSS网页设计与布局从入门到精通</a>”这本书，翻到150页，第11.5节“图片与文字的对齐方式”，第2小节：“纵向对齐方式”，那么就一切真相大白了。这一小节讲的是：图像与它旁边文本之间的纵向对向方式由 vertical-align 属性控制，默认值为 baseline 方式，即“基线”对齐。</p>
<p>什么是基线呢？就是上面图中abc这三个字母的底端所在的水平线，英文26个字母，绝大部分都是没有“钩”的，他们的下端都是对齐于基线的，而默认下情况，图像与它旁边的文字也是基线对齐的，<font color="#FF0000">也就是说，你可以把这幅图像想象成一个字母，那么这个缝隙就存在了</font>。</p>
<p>而在Firefox和IE 8种，为什么没有这条缝隙呢？是因为他们在对于只有图像，而旁边没有字母的时候，做了不同的处理。如果你用IE8查看一下加了字母以后效果，可以看到同样出现了这个缝隙。</p>
<h4>第四步：解决</h4>
<p>到这里，我们就可以非常容易地把这个缝隙去掉了： 给图片增加一个CSS设置，使图像与文字的底端，而不是基线对齐就可以了。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre>&lt;body&gt;
        &lt;div style=&quot;border:1px solid #FF0000;&quot;&gt;
              &lt;img src=&quot;images/logo1.jpg&quot; style=&quot;vertical-align:text-bottom&quot;&gt;
        &lt;/div&gt;
&lt;/body&gt;</pre></td></tr></table></div>

<h4>第五步：总结</h4>
<p>到这里，问题就解决了。从这个问题，我们可以总结几点。</p>
<p>1：要善于调试，善于从蛛丝马迹中寻找问题的本质原因。</p>
<p>2：调试的最重要的手段就是“简化代码、暴露问题”，要隔离出一段出现问题的最小代码集，这样寻找问题的解决方法就会容易得的。</p>
<p>3：要善于联想，尝试添加一些“辅助线”，帮你找到问题的关键。</p>
<p>4：基础知识要扎实，如果你根本就不知道有  vertical-align这样一回事，那么再怎么联系也没有用的。</p>
<p>5：书上的东西都是原理，真正如何灵活地运用到工作中，还需要靠不断地积累经验。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090327.vertical-align-application.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>你问我答(33)——jQeury实现限定上限的多选表单</title>
		<link>http://learning.artech.cn/20090320.jquery-limmited-multiple-choice.html</link>
		<comments>http://learning.artech.cn/20090320.jquery-limmited-multiple-choice.html#comments</comments>
		<pubDate>Fri, 20 Mar 2009 08:39:16 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[你问我答]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090320.jquery-limmited-multiple-choice.html</guid>
		<description><![CDATA[jQeury在网页开发中非常有用，我们以前也说过几次，今天遇到一位读者的问题：

“老师好，请教一个js的问题！最近在做一个20选10的投票系统，客户要求每次投票的选项不能超过10个，超过10... ]]></description>
			<content:encoded><![CDATA[<p>jQeury在网页开发中非常有用，我们以前也说过几次，今天遇到一位读者的问题：</p>
<p style="color:#900">
“老师好，请教一个js的问题！最近在做一个20选10的投票系统，客户要求每次投票的选项不能超过10个，超过10个就不能投票。（即小于或等于10），请问如何用js来检测每次投票的选项不能超过10个啊？谢谢！”
</p>
<p>这里我就用jQeury来解决一下这位读者的问题，为了代码简单，我做一个共有5个备选选项，最多允许选择2项的例子。</p>
<p>首先写出HTML</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre>    &lt;div id=&quot;optionDiv&quot;&gt;
        &lt;input id=&quot;Checkbox1&quot; type=&quot;checkbox&quot; /&gt; &lt;label for=&quot;Checkbox1&quot;&gt;选项A&lt;/label&gt;&lt;br /&gt;
        &lt;input id=&quot;Checkbox2&quot; type=&quot;checkbox&quot; /&gt; &lt;label for=&quot;Checkbox2&quot;&gt;选项B&lt;/label&gt;&lt;br /&gt;
        &lt;input id=&quot;Checkbox3&quot; type=&quot;checkbox&quot; /&gt; &lt;label for=&quot;Checkbox3&quot;&gt;选项C&lt;/label&gt;&lt;br /&gt;
        &lt;input id=&quot;Checkbox4&quot; type=&quot;checkbox&quot; /&gt; &lt;label for=&quot;Checkbox4&quot;&gt;选项D&lt;/label&gt;&lt;br /&gt;
        &lt;input id=&quot;Checkbox5&quot; type=&quot;checkbox&quot; /&gt; &lt;label for=&quot;Checkbox5&quot;&gt;选项E&lt;/label&gt;&lt;br /&gt;
    &lt;/div&gt;</pre></td></tr></table></div>

<p>HTML很简单，不再解释，接下来看一下jQuery的代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="javascript">&lt;script type=<span style="color: #3366CC;">&quot;text/javascript&quot;</span> src=<span style="color: #3366CC;">&quot;jquery.js&quot;</span> &gt;&lt;/script&gt;
&lt;script type=<span style="color: #3366CC;">&quot;text/javascript&quot;</span>&gt;
        $<span style="color: #66cc66;">&#40;</span>pageLoaded<span style="color: #66cc66;">&#41;</span>;
&nbsp;
        <span style="color: #003366; font-weight: bold;">function</span> pageLoaded<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;#optionDiv input:checkbox&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span>checkboxClicked<span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
&nbsp;
        <span style="color: #003366; font-weight: bold;">function</span> checkboxClicked<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> 
           <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;#optionDiv input:checkbox:checked&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">length</span> &gt; <span style="color: #CC0000;">2</span><span style="color: #66cc66;">&#41;</span>
                      $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;checked&quot;</span>, <span style="color: #003366; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>
&lt;/script&gt;</pre></td></tr></table></div>

<p><a href="http://learning.artech.cn/20080828.master-javascript-jquery-published.html" target="_blank"><img style="float:right;padding:1px;" border="0" src="http://learning.artech.cn/uploads/blog-images/master-css-div-shadow.jpg" width="120" /></a><a target="_blank" href="http://learning.artech.cn/wp-content/uploads/2009/03/jquery-multiple-choice-demo.html">点击这里看一下效果演示</a>。下面简单解释一下原理，上面代码中：</p>
<p>第1行的作用是引入jQeury库文件，第2~13行的作用就是实现5个选项中限制最多选两项的代码。</p>
<p>第3行中，“$”是一个jquey定义的函数，它的作用是定义在整个页面装载到浏览器以后，执行括号中指定的函数，也就是下面定义的pageLoaded函数。</p>
<p>第5~7行就定义了这个pageLoaded函数，函数执行的代码就是第8行中的内容，即首先选中id为optionDIV中所有checkbox元素，并为每一个选中的checkbox元素设定被鼠标单击时的行为，即执行括号中的函数，也就是checkboxClicked函数。</p>
<p>第9~12行就定义了checkboxClicked函数，其功能也很简单，但某个checkbox被单击以后，判断一下一共有多少个checkbox被选中了，如果这个数量大于2，那么就把当前点击的这个checkbox的checked属性，设置为false，这样这次点击就被取消了。</p>
<p>说明：</p>
<p>如果读者对上面代码还有不清楚的地方，请看看我们的视频教程：http://learning.artech.cn/category/javscript-jquery ，里面对Javascript和jQuery作了比较详细的讲解。</p>
<p>从上面代码中可以看到，Javascript不同传统的静态高级语言的一个地方是，它可以非常方便地把函数作为参数传递，这一点很灵活，上面的代码也可以写成下面的样子，效果完全相同。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="javascript">        $<span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;#optionDiv input:checkbox&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">click</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;#optionDiv input:checkbox:checked&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">length</span> &gt; <span style="color: #CC0000;">2</span><span style="color: #66cc66;">&#41;</span>
                      $<span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">attr</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;checked&quot;</span>, <span style="color: #003366; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090320.jquery-limmited-multiple-choice.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>CSS调试工具推荐 —— IE Tester</title>
		<link>http://learning.artech.cn/20090316.ie-tester-recommendation.html</link>
		<comments>http://learning.artech.cn/20090316.ie-tester-recommendation.html#comments</comments>
		<pubDate>Mon, 16 Mar 2009 02:08:58 +0000</pubDate>
		<dc:creator>chance</dc:creator>
		
		<category><![CDATA[网页设计杂谈]]></category>

		<guid isPermaLink="false">http://learning.artech.cn/20090316.ie-tester-recommendation.html</guid>
		<description><![CDATA[相信有一点经验的读者都会感到，使用CSS进行页面布局，调试是个大麻烦。特别是IE浏览器，各种版本都要测试，为此我们需要想各种方法，在自己的机器上按装各种版本的浏览器，这是很麻烦... ]]></description>
			<content:encoded><![CDATA[<p>相信有一点经验的读者都会感到，使用CSS进行页面布局，调试是个大麻烦。特别是IE浏览器，各种版本都要测试，为此我们需要想各种方法，在自己的机器上按装各种版本的浏览器，这是很麻烦的事情。</p>
<p>有今天介绍的这个软件，就轻松多了—— IE Tester。IETester 是一个免费的浏览器，它同时包括了IE  5.5、IE  6、IE  7、IE  8 RC1的所有内核，所以你可以非常方便地使用它来对你设计制作的页面进行测试。以保证你设计的页面可以在各种IE浏览器中正确显示。</p>
<p><center><img src='http://learning.artech.cn/wp-content/uploads/2009/03/ie-tester.png' alt='IE-Tester' /></center></p>
<p>IE Tester 目前的最新版本是 V0.3 , 网站地址：<a href="http://www.my-debugbar.com/wiki/IETester/HomePage">http://www.my-debugbar.com/wiki/IETester/HomePage</a>。<a href="http://www.my-debugbar.com/ietester/install-ietester-v0.3.exe">也可以直接下载</a>。他们还提供不少其他的Web设计开发中可以用得上的辅助工具，有兴趣的读者可以看一下。</p>
]]></content:encoded>
			<wfw:commentRss>http://learning.artech.cn/20090316.ie-tester-recommendation.html/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
