<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_study log</title><subtitle type="text"/><id>http://feed.cnblogs.com/blog/u/23983/rss</id><updated>2012-01-01T05:59:31Z</updated><author><name>lin-zhang</name><uri>http://www.cnblogs.com/michael-zhang/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/michael-zhang/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/23983/rss"/><entry><id>http://www.cnblogs.com/michael-zhang/archive/2012/01/01/2309438.html</id><title type="text">[转]Linux 经典书籍推荐</title><summary type="text">入门篇 《LINUX权威指南》书不错，写的很全面也比较广，涉及的不深，做为入门书籍不错，可以比较全面的了解linux 。另外比较热门的也可以看看《鸟哥的私房菜》等书，偏管理类的书。如果想做server方向的可以找来看看。	Running Linux, 5th Edition驱动篇 《LINUX设备驱动程序 》就是网上说的“LDD”，经典之作，必备书籍。国产经典《Linux驱动详细解》也是一本非常不错的书，很实用，书中源代码 分析比较多，基于2440的，对linux外围驱动有很全面的讲解	Linux Device Drivers, 3rd Edition - O&amp;#39;Reilly内核篇 浙江</summary><published>2012-01-01T06:00:00Z</published><updated>2012-01-01T06:00:00Z</updated><author><name>lin-zhang</name><uri>http://www.cnblogs.com/michael-zhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/michael-zhang/archive/2012/01/01/2309438.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/michael-zhang/archive/2012/01/01/2309438.html"/><content type="html">&lt;div&gt;&lt;div&gt;&lt;strong style="font-size: 8pt; "&gt;入门篇&amp;nbsp;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 8pt; "&gt;&amp;nbsp; &amp;nbsp; 《LINUX权威指南》书不错，写的很全面也比较广，涉及的不深，做为入门书籍不错，可以比较全面的了解linux 。另外比较热门的也可以看看《鸟哥的私房菜》等书，偏管理类的书。如果想做server方向的可以找来看看。&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;	&lt;/span&gt;&lt;span style="font-size: 8pt; "&gt;Running Linux, 5th Edition&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;strong style="font-size: 8pt; "&gt;驱动篇&amp;nbsp;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 8pt; "&gt;&amp;nbsp; &amp;nbsp; 《LINUX设备驱动程序 》就是网上说的&amp;#8220;LDD&amp;#8221;，经典之作，必备书籍。国产经典《Linux驱动详细解》也是一本非常不错的书，很实用，书中源代码 分析比较多，基于2440的，对linux外围驱动有很全面的讲解&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;	&lt;/span&gt;&lt;span style="font-size: 8pt; "&gt;Linux Device Drivers, 3rd Edition - O'Reilly&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;strong style="font-size: 8pt; "&gt;内核篇&amp;nbsp;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 8pt; "&gt;&amp;nbsp; &amp;nbsp; 浙江大学的《LINUX内核源代码情景分析》，外国鬼子的《莱昂氏UNIX源代码分析》还有《深入理解linux内核》都是出名的经典巨作。另外赵炯的《LINUX内核完全剖析--基于0.12内核》也非常不错，对内核代码进行了详细的注释，非常有助于对内核的理解和代码的分析。&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;	&lt;/span&gt;&lt;span style="font-size: 8pt; "&gt;Understanding the Linux Kernel, 3rd Edition&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;strong style="font-size: 8pt; "&gt;shell篇&amp;nbsp;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 8pt; "&gt;&amp;nbsp; &amp;nbsp; 《LINUX与UNIX Shell编程指南》&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;	&lt;/span&gt;&lt;span style="font-size: 8pt; "&gt;Linux.and.Unix.Shell.Programming&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;strong style="font-size: 8pt; "&gt;应用 编程&amp;nbsp;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 8pt; "&gt;&amp;nbsp; &amp;nbsp; 不用说了肯定是《unix环境高级编程》被称为unix编程的圣经。&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;	&lt;/span&gt;&lt;span style="font-size: 8pt; "&gt;Advanced programming in the unix(r) environment (2nd edition)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;strong style="font-size: 8pt; "&gt;TCP/IP篇&amp;nbsp;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 8pt; "&gt;&amp;nbsp; &amp;nbsp; 《TCP/IP详解》作者W.Richard Stevens也是《unix环境高级编程》的作者，牛人出的书没有一本不是经典的。但是英年早逝，默哀一下&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;	&lt;/span&gt;&lt;span style="font-size: 8pt; "&gt;TCP.IP Illustrated&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;strong style="font-size: 8pt; "&gt;c语言&amp;nbsp;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 8pt; "&gt;&amp;nbsp; &amp;nbsp; 《The C Programming Language》正是作者造出来的c语言，书能垃圾就怪了&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 8pt; "&gt;&amp;nbsp; &amp;nbsp; 《c和指针》和《c缺陷和陷阱》两本必备。包含了c语言最容易出错的地方，加深c语言功力的好材料。&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;	&lt;/span&gt;&lt;span style="font-size: 8pt; "&gt;The C programming Language&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;	&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;strong style="font-size: 8pt; "&gt;关于算法&amp;nbsp;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 8pt; "&gt;&amp;nbsp; &amp;nbsp; 《算法导论》&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="white-space:pre"&gt;	&lt;/span&gt;&lt;span style="font-size: 8pt; "&gt;麻省算法导论全集（教材+讲义+答桉）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://kinglaw05.blog.163.com/blog/static/5968331420103301931422/"&gt;&lt;span style="font-size: 8pt; "&gt;http://kinglaw05.blog.163.com/blog/static/5968331420103301931422/&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href="http://mikewootc.blog.163.com/blog/static/8311285820091171513864/"&gt;&lt;span style="font-size: 8pt; "&gt;http://mikewootc.blog.163.com/blog/static/8311285820091171513864/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/michael-zhang/aggbug/2309438.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/michael-zhang/archive/2012/01/01/2309438.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/michael-zhang/archive/2012/01/01/2309431.html</id><title type="text">HTML5 &amp;amp; js</title><summary type="text">Table of Contents HTML5 Overview.. 2 Canvas 2D drawing, interactive. 3 Js animation &amp;amp; async. 4 Js class, ‘delegate’ &amp;amp; Inheritance. 5 HTML5 Overview HTML5 ~= HTML + C...</summary><published>2012-01-01T05:49:00Z</published><updated>2012-01-01T05:49:00Z</updated><author><name>lin-zhang</name><uri>http://www.cnblogs.com/michael-zhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/michael-zhang/archive/2012/01/01/2309431.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/michael-zhang/archive/2012/01/01/2309431.html"/><content type="html">&lt;html&gt;&#xD;
     &lt;head&gt;&#xD;
         &lt;meta http-equiv="Content-Type" content="text/html; charset=gb2312" /&gt;&#xD;
         &lt;meta name="Generator" content="Microsoft Word 12 (filtered)" /&gt;&lt;style&gt; &lt;!&#xD;
         -- /* Font Definitions */ @&#xD;
         font-face&#xD;
         {&#xD;
         font-family: 宋体;&#xD;
         panose-1: 2 1 6 0 3 1 1 1 1 1;&#xD;
         }&#xD;
         @font-face&#xD;
         {&#xD;
         font-family: "Cambria Math";&#xD;
         panose-1: 2 4 5 3 5 4 6 3 2 4;&#xD;
         }&#xD;
         @font-face&#xD;
         {&#xD;
         font-family: Cambria;&#xD;
         panose-1: 2 4 5 3 5 4 6 3 2 4;&#xD;
         }&#xD;
         @font-face&#xD;
         {&#xD;
         font-family: Calibri;&#xD;
         panose-1: 2 15 5 2 2 2 4 3 2 4;&#xD;
         }&#xD;
         @font-face&#xD;
         {&#xD;
         font-family: "\@宋体";&#xD;
         panose-1: 2 1 6 0 3 1 1 1 1 1;&#xD;
         }&#xD;
         /* Style Definitions */p.MsoNormal, li.MsoNormal, div.MsoNormal&#xD;
         {&#xD;
         margin: 0cm;&#xD;
         margin-bottom: .0001pt;&#xD;
         text-align: justify;&#xD;
         text-justify: inter-ideograph;&#xD;
         font-size: 10.5pt;&#xD;
         font-family: "Calibri" , "sans-serif";&#xD;
         }&#xD;
         h1&#xD;
         {&#xD;
         mso-style-link: "Heading 1 Char";&#xD;
         margin-top: 17.0pt;&#xD;
         margin-right: 0cm;&#xD;
         margin-bottom: 16.5pt;&#xD;
         margin-left: 0cm;&#xD;
         text-align: justify;&#xD;
         text-justify: inter-ideograph;&#xD;
         line-height: 240%;&#xD;
         page-break-after: avoid;&#xD;
         font-size: 22.0pt;&#xD;
         font-family: "Calibri" , "sans-serif";&#xD;
         }&#xD;
         h2&#xD;
         {&#xD;
         mso-style-link: "Heading 2 Char";&#xD;
         margin-top: 13.0pt;&#xD;
         margin-right: 0cm;&#xD;
         margin-bottom: 13.0pt;&#xD;
         margin-left: 0cm;&#xD;
         text-align: justify;&#xD;
         text-justify: inter-ideograph;&#xD;
         line-height: 173%;&#xD;
         page-break-after: avoid;&#xD;
         font-size: 16.0pt;&#xD;
         font-family: "Cambria" , "serif";&#xD;
         }&#xD;
         p.MsoToc1, li.MsoToc1, div.MsoToc1&#xD;
         {&#xD;
         margin: 0cm;&#xD;
         margin-bottom: .0001pt;&#xD;
         text-align: justify;&#xD;
         text-justify: inter-ideograph;&#xD;
         font-size: 10.5pt;&#xD;
         font-family: "Calibri" , "sans-serif";&#xD;
         }&#xD;
         p.MsoToc2, li.MsoToc2, div.MsoToc2&#xD;
         {&#xD;
         margin-top: 0cm;&#xD;
         margin-right: 0cm;&#xD;
         margin-bottom: 5.0pt;&#xD;
         margin-left: 11.0pt;&#xD;
         line-height: 115%;&#xD;
         font-size: 11.0pt;&#xD;
         font-family: "Calibri" , "sans-serif";&#xD;
         }&#xD;
         p.MsoToc3, li.MsoToc3, div.MsoToc3&#xD;
         {&#xD;
         margin-top: 0cm;&#xD;
         margin-right: 0cm;&#xD;
         margin-bottom: 5.0pt;&#xD;
         margin-left: 22.0pt;&#xD;
         line-height: 115%;&#xD;
         font-size: 11.0pt;&#xD;
         font-family: "Calibri" , "sans-serif";&#xD;
         }&#xD;
         a:link, span.MsoHyperlink&#xD;
         {&#xD;
         color: blue;&#xD;
         text-decoration: underline;&#xD;
         }&#xD;
         a:visited, span.MsoHyperlinkFollowed&#xD;
         {&#xD;
         color: purple;&#xD;
         text-decoration: underline;&#xD;
         }&#xD;
         p.MsoAcetate, li.MsoAcetate, div.MsoAcetate&#xD;
         {&#xD;
         mso-style-link: "Balloon Text Char";&#xD;
         margin: 0cm;&#xD;
         margin-bottom: .0001pt;&#xD;
         text-align: justify;&#xD;
         text-justify: inter-ideograph;&#xD;
         font-size: 8.0pt;&#xD;
         font-family: "Calibri" , "sans-serif";&#xD;
         }&#xD;
         p.MsoTocHeading, li.MsoTocHeading, div.MsoTocHeading&#xD;
         {&#xD;
         margin-top: 24.0pt;&#xD;
         margin-right: 0cm;&#xD;
         margin-bottom: 0cm;&#xD;
         margin-left: 0cm;&#xD;
         margin-bottom: .0001pt;&#xD;
         line-height: 115%;&#xD;
         page-break-after: avoid;&#xD;
         font-size: 14.0pt;&#xD;
         font-family: "Cambria" , "serif";&#xD;
         color: #365F91;&#xD;
         font-weight: bold;&#xD;
         }&#xD;
         span.Heading1Char&#xD;
         {&#xD;
         mso-style-name: "Heading 1 Char";&#xD;
         mso-style-link: "Heading 1";&#xD;
         font-weight: bold;&#xD;
         }&#xD;
         span.Heading2Char&#xD;
         {&#xD;
         mso-style-name: "Heading 2 Char";&#xD;
         mso-style-link: "Heading 2";&#xD;
         font-family: "Cambria" , "serif";&#xD;
         font-weight: bold;&#xD;
         }&#xD;
         span.apple-style-span&#xD;
         {&#xD;
         mso-style-name: apple-style-span;&#xD;
         }&#xD;
         span.apple-converted-space&#xD;
         {&#xD;
         mso-style-name: apple-converted-space;&#xD;
         }&#xD;
         span.BalloonTextChar&#xD;
         {&#xD;
         mso-style-name: "Balloon Text Char";&#xD;
         mso-style-link: "Balloon Text";&#xD;
         }&#xD;
         /* Page Definitions */@page Section1&#xD;
         {&#xD;
         size: 595.3pt 841.9pt;&#xD;
         margin: 72.0pt 90.0pt 72.0pt 90.0pt;&#xD;
         layout-grid: 15.6pt;&#xD;
         }&#xD;
         div.Section1&#xD;
         {&#xD;
         page: Section1;&#xD;
         }&#xD;
         -- &gt;&lt;/style&gt;&#xD;
     &lt;/head&gt;&#xD;
     &lt;body lang="ZH-CN" link="blue" vlink="purple" style='text-justify-trim: punctuation'&gt;&#xD;
         &lt;div  style='layout-grid: 15.6pt'&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;Table of Contents&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="#_Toc309058913"&gt;HTML5 Overview&lt;span style='color: windowtext;&#xD;
         display: none; text-decoration: none'&gt;.. &lt;/span&gt;&lt;span style='color: windowtext; display: none;&#xD;
         text-decoration: none'&gt;2&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="#_Toc309058914"&gt;Canvas 2D drawing, interactive&lt;span style='color: windowtext;&#xD;
         display: none; text-decoration: none'&gt;. &lt;/span&gt;&lt;span style='color: windowtext; display: none;&#xD;
         text-decoration: none'&gt;3&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="#_Toc309058915"&gt;Js animation &amp;amp; async&lt;span style='color: windowtext;&#xD;
         display: none; text-decoration: none'&gt;. &lt;/span&gt;&lt;span style='color: windowtext; display: none;&#xD;
         text-decoration: none'&gt;4&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="#_Toc309058916"&gt;Js class, &amp;#8216;&lt;em&gt;delegate&lt;/em&gt;&amp;#8217; &amp;amp; Inheritance&lt;span&#xD;
         style='color: windowtext; display: none; text-decoration: none'&gt;. &lt;/span&gt;&lt;span style='color: windowtext;&#xD;
         display: none; text-decoration: none'&gt;5&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;span lang="EN-US" style='font-size: 10.5pt; font-family: "Calibri","sans-serif"'&gt;&lt;br clear="all" style='page-break-before: always' /&gt;&#xD;
         &lt;/span&gt;&#xD;
         &lt;p  align="left" style='text-align: left'&gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p&gt;&lt;strong&gt;&lt;a name="_Toc309058913"&gt;&lt;span lang="EN-US"&gt;HTML5 Overview&lt;/span&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://dev.w3.org/html5/spec/Overview.html"&gt;HTML5&lt;/a&gt; ~= &lt;a href="http://en.wikipedia.org/wiki/HTML5"&gt;HTML&lt;/a&gt; + &lt;a href="http://en.wikipedia.org/wiki/CSS3#CSS_3"&gt;CSS&lt;/a&gt; + &lt;a href="http://en.wikipedia.org/wiki/JavaScript"&gt;Javascript&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;New features: Offline storage database, Realtime Communication, Drag-and-drop,&#xD;
         Graphics, Multimedia, &lt;a href="http://en.wikipedia.org/wiki/WebGL"&gt;WebGL&lt;/a&gt;&amp;#8230;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;Organization &amp; Standards: &lt;a href="http://en.wikipedia.org/wiki/WHATWG"&gt;WHATWG&lt;/a&gt;(HTML5), &lt;a href="http://en.wikipedia.org/wiki/W3C"&gt;W3C&lt;/a&gt;(CSS, HTML, XML, SOAP, ...), &lt;a href="http://en.wikipedia.org/wiki/Ecma_International"&gt;ECMA&lt;/a&gt;(&lt;a href="http://en.wikipedia.org/wiki/ECMAScript"&gt;ECMAScript&lt;/a&gt;, CLI, ...)&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://slides.html5rocks.com/"&gt;http://slides.html5rocks.com/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;Browser Supports:&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://findmebyip.com/litmus/"&gt;http://findmebyip.com/litmus/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://html5test.com/"&gt;http://html5test.com/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;Video/Audio Supports:&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://diveintohtml5.info/video.html"&gt;http://diveintohtml5.info/video.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://en.wikipedia.org/wiki/HTML5_video"&gt;http://en.wikipedia.org/wiki/HTML5_video&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;Media Capture:&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.w3.org/TR/html-media-capture/"&gt;http://www.w3.org/TR/html-media-capture/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/video-conferencing-and-peer-to-peer-communication.html"&gt;http://www.whatwg.org/specs/web-apps/current-work/multipage/video-conferencing-and-peer-to-peer-communication.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.taboca.com/p/camcanvas/"&gt;http://www.taboca.com/p/camcanvas/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;vs Flash/Silverlight/.. :&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.apple.com/hotnews/thoughts-on-flash/"&gt;Thoughts on Flash (Steve Jobs, 2010.4)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://en.wikipedia.org/wiki/Comparison_of_HTML5_and_Flash"&gt;http://en.wikipedia.org/wiki/Comparison_of_HTML5_and_Flash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.zdnet.com/blog/microsoft/will-there-be-a-silverlight-6-and-does-it-matter/11180"&gt;Will there be a Silverlight 6 (and does it matter)?&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.zdnet.com/blog/microsoft/microsoft-our-strategy-with-silverlight-has-shifted/7834?tag=content;siu-container"&gt; Microsoft&amp;#8217;s strategy with Silverlight shifted&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;Mobile Browser Supports:&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://en.wikipedia.org/wiki/HTML5_in_mobile_devices"&gt;http://en.wikipedia.org/wiki/HTML5_in_mobile_devices&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://jquerymobile.com/"&gt;http://jquerymobile.com/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://phonegap.com/"&gt;http://phonegap.com/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;Graphic Designer:&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://en.wikipedia.org/wiki/Adobe_Edge"&gt;http://en.wikipedia.org/wiki/Adobe_Edge&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.adobe.com/devnet/edge/articles/guide-to-edge.html"&gt;http://www.adobe.com/devnet/edge/articles/guide-to-edge.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;Showcase&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.chromeexperiments.com/"&gt;http://www.chromeexperiments.com/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://mugtug.com/sketchpad/"&gt;http://mugtug.com/sketchpad/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://fir.sh/projects/jsnes/"&gt;http://fir.sh/projects/jsnes/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;#8230;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;span lang="EN-US" style='font-size: 10.5pt; font-family: "Calibri","sans-serif"'&gt;&lt;br clear="all" style='page-break-before: always' /&gt;&#xD;
         &lt;/span&gt;&#xD;
         &lt;p  align="left" style='text-align: left'&gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p&gt;&lt;strong&gt;&lt;a name="_Toc309058914"&gt;&lt;span lang="EN-US"&gt;Canvas 2D drawing, interactive&lt;/span&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;API:&amp;nbsp; &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html"&gt; http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;Tutorials:&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://home.cogeco.ca/~ve3ll/jstutorg.htm"&gt;http://home.cogeco.ca/~ve3ll/jstutorg.htm&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://simonsarris.com/blog/225-canvas-selecting-resizing-shape"&gt; http://simonsarris.com/blog/225-canvas-selecting-resizing-shape&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.html5canvastutorials.com/"&gt;http://www.html5canvastutorials.com/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span lang="EN-US"&gt;Codes:&lt;a href='#' onclick="javascript:doc = window.open().document; doc.write(document.getElementById('txt2').value); doc.close(); return false;"&gt;Run&lt;/a&gt;&lt;textarea id='txt2' rows="30" cols="90"&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&amp;gt;&amp;#13;&amp;#10;&amp;lt;html&amp;gt;&amp;#13;&amp;#10;&amp;lt;head&amp;gt;&amp;#13;&amp;#10; &amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&amp;#13;&amp;#10; #cv1&amp;#13;&amp;#10; {&amp;#13;&amp;#10;/* http://www.colorzilla.com/gradient-editor/ */&amp;#13;&amp;#10;background: #a5c956; /* Old browsers */&amp;#13;&amp;#10;background: -moz-linear-gradient(top, rgba(165,201,86,1) 0%, rgba(205,235,142,1) 100%); /* FF3.6+ */&amp;#13;&amp;#10;background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(165,201,86,1)), color-stop(100%,rgba(205,235,142,1))); /* Chrome,Safari4+ */&amp;#13;&amp;#10;background: -webkit-linear-gradient(top, rgba(165,201,86,1) 0%,rgba(205,235,142,1) 100%); /* Chrome10+,Safari5.1+ */&amp;#13;&amp;#10;background: -o-linear-gradient(top, rgba(165,201,86,1) 0%,rgba(205,235,142,1) 100%); /* Opera 11.10+ */&amp;#13;&amp;#10;background: -ms-linear-gradient(top, rgba(165,201,86,1) 0%,rgba(205,235,142,1) 100%); /* IE10+ */&amp;#13;&amp;#10;background: linear-gradient(top, rgba(165,201,86,1) 0%,rgba(205,235,142,1) 100%); /* W3C */&amp;#13;&amp;#10;filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a5c956', endColorstr='#cdeb8e',GradientType=0 ); /* IE6-9 */&amp;#13;&amp;#10; }&amp;#13;&amp;#10; &amp;lt;/style&amp;gt;&amp;#13;&amp;#10; &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;#13;&amp;#10; var select1, canv, ctx;&amp;#13;&amp;#10; &amp;#13;&amp;#10; function draw(iScale) {&amp;#13;&amp;#10; ctx.clearRect(0, 0, 700, 400);&amp;#13;&amp;#10; ctx.save();&amp;#13;&amp;#10; ctx.scale(iScale, iScale);&amp;#13;&amp;#10; //ctx.rotate(-Math.PI / 4); //ctx.rotate(-Math.PI * 2);&amp;#13;&amp;#10;&amp;#13;&amp;#10; ctx.fillStyle = &amp;quot;#c80000&amp;quot;;&amp;#13;&amp;#10; ctx.fillRect(10, 20, 50, 50);&amp;#13;&amp;#10; ctx.fillStyle = &amp;quot;rgba(0,0,200,0.5)&amp;quot;;&amp;#13;&amp;#10; ctx.fillRect(30, 40, 50, 50);&amp;#13;&amp;#10; ctx.strokeStyle = '#fff';&amp;#13;&amp;#10; ctx.lineWidth = 2;&amp;#13;&amp;#10; ctx.strokeRect(30, 40, 50, 50);&amp;#13;&amp;#10;&amp;#13;&amp;#10; ctx.font = '2em sans-serif';&amp;#13;&amp;#10; ctx.textBaseline = 'top';&amp;#13;&amp;#10; ctx.lineWidth = 1;&amp;#13;&amp;#10; ctx.fillStyle = '#000';&amp;#13;&amp;#10; ctx.strokeStyle = '#fff';&amp;#13;&amp;#10; ctx.fillText('Canvas', 120, 10);&amp;#13;&amp;#10; ctx.strokeText('2D Drawing', 240, 10);&amp;#13;&amp;#10;&amp;#13;&amp;#10; ctx.beginPath();&amp;#13;&amp;#10; ctx.arc(200, 100, 30, 0, Math.PI * 1.5, false);&amp;#13;&amp;#10; ctx.closePath();&amp;#13;&amp;#10; ctx.fill();&amp;#13;&amp;#10;&amp;#13;&amp;#10; ctx.beginPath();&amp;#13;&amp;#10; ctx.arc(300, 100, 30, 0, Math.PI * 2, true);&amp;#13;&amp;#10; ctx.closePath();&amp;#13;&amp;#10; ctx.stroke();&amp;#13;&amp;#10;&amp;#13;&amp;#10; ctx.strokeStyle = '#000';&amp;#13;&amp;#10; ctx.beginPath();&amp;#13;&amp;#10; ctx.moveTo(10, 200);&amp;#13;&amp;#10; ctx.lineTo(90, 300);&amp;#13;&amp;#10; ctx.lineTo(90, 200);&amp;#13;&amp;#10; ctx.closePath();&amp;#13;&amp;#10; ctx.stroke();&amp;#13;&amp;#10;&amp;#13;&amp;#10; var img = new Image();&amp;#13;&amp;#10; img.onload = function() {&amp;#13;&amp;#10; var width = 90;&amp;#13;&amp;#10; width *= iScale; //scale image size&amp;#13;&amp;#10; ctx.drawImage(img, 260, 200, width, width);&amp;#13;&amp;#10; };&amp;#13;&amp;#10; img.src = 'http://images.weiphone.com/attachments/Day_090828/22_270438_b871908fc2cccdc.jpg';&amp;#13;&amp;#10;&amp;#13;&amp;#10; ctx.restore();&amp;#13;&amp;#10; }&amp;#13;&amp;#10; window.onload = function() {&amp;#13;&amp;#10; select1 = document.getElementById('sel1');&amp;#13;&amp;#10; for (var i = 0.2; i &amp;lt; 1.6; i += 0.2) {&amp;#13;&amp;#10; select1.add(new Option(i));&amp;#13;&amp;#10; }&amp;#13;&amp;#10; select1.selectedIndex = 4;&amp;#13;&amp;#10; select1['onchange'] = function() {&amp;#13;&amp;#10; var idx = select1.selectedIndex;&amp;#13;&amp;#10; var obj = select1.options[idx];&amp;#13;&amp;#10; draw(obj.innerText);&amp;#13;&amp;#10; };&amp;#13;&amp;#10;&amp;#13;&amp;#10; canv = document.getElementById('cv1');&amp;#13;&amp;#10; ctx = canv.getContext(&amp;quot;2d&amp;quot;);&amp;#13;&amp;#10; canv['onmousemove'] = function(e) {&amp;#13;&amp;#10; document.getElementById('txt1').value = (e.clientX - canv.offsetLeft) + ',' + (e.clientY - canv.offsetTop);&amp;#13;&amp;#10; }&amp;#13;&amp;#10;&amp;#13;&amp;#10; draw(1);&amp;#13;&amp;#10; }&amp;#13;&amp;#10; &amp;lt;/script&amp;gt;&amp;#13;&amp;#10;&amp;lt;/head&amp;gt;&amp;#13;&amp;#10;&amp;lt;body&amp;gt;&amp;#13;&amp;#10; &amp;lt;div&amp;gt;Scale: &amp;lt;select id='sel1'&amp;gt;&amp;lt;/select&amp;gt;&amp;amp;nbsp;Mouse Position:&amp;lt;input type='text' id='txt1' /&amp;gt;&amp;lt;/div&amp;gt;&amp;#13;&amp;#10; &amp;lt;canvas id=&amp;quot;cv1&amp;quot; width=&amp;quot;700&amp;quot; height=&amp;quot;400&amp;quot;&amp;gt;Your browser does not support Canvas&amp;lt;/canvas&amp;gt;&amp;#13;&amp;#10;&amp;lt;/body&amp;gt;&amp;#13;&amp;#10;&amp;lt;/html&amp;gt;&lt;/textarea&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;span lang="EN-US" style='font-size: 10.5pt; font-family: "Calibri","sans-serif"'&gt;&lt;br clear="all" style='page-break-before: always' /&gt;&#xD;
         &lt;/span&gt;&#xD;
         &lt;p  align="left" style='text-align: left'&gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p&gt;&lt;strong&gt;&lt;a name="_Toc309058915"&gt;&lt;span lang="EN-US"&gt;Js animation &amp;amp; async&lt;/span&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.w3school.com.cn/htmldom/met_win_setinterval.asp"&gt; setInterval&lt;/a&gt; / &lt;a href="http://www.w3school.com.cn/htmldom/met_win_clearinterval.asp"&gt; clearInterval&lt;/a&gt;, &lt;a href="http://www.w3school.com.cn/htmldom/met_win_settimeout.asp"&gt; setTimeout&lt;/a&gt; / &lt;a href="http://www.w3school.com.cn/htmldom/met_win_cleartimeout.asp"&gt; clearTimeout&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span lang="EN-US"&gt;Codes:&lt;a href='#' onclick="javascript:doc = window.open().document; doc.write(document.getElementById('txt3').value); doc.close(); return false;"&gt;Run&lt;/a&gt;&lt;textarea id='txt3' rows="30" cols="90"&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&amp;gt;&amp;#13;&amp;#10;&amp;lt;html&amp;gt;&amp;#13;&amp;#10;&amp;lt;head&amp;gt;&amp;#13;&amp;#10; &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;#13;&amp;#10; var ck1, ck2, itv1, itv2, cv1, ctx,x, div2, wid2, hei2;&amp;#13;&amp;#10; var INTERVAL1 = 50, INTERVAL2 = 50;&amp;#13;&amp;#10;&amp;#13;&amp;#10; function animate1() {&amp;#13;&amp;#10; ctx.clearRect(x, 20, 50, 50); //clear previous drawing&amp;#13;&amp;#10; x += 5;&amp;#13;&amp;#10; if (x &amp;gt;= 800) x = 1;&amp;#13;&amp;#10; ctx.fillRect(x, 20, 50, 50);&amp;#13;&amp;#10; }&amp;#13;&amp;#10;&amp;#13;&amp;#10; function animate2() {&amp;#13;&amp;#10; wid2 += 5;&amp;#13;&amp;#10; hei2 += 1.5;&amp;#13;&amp;#10; if (wid2 &amp;gt;= 800) {&amp;#13;&amp;#10; wid2 = hei2 = 1;&amp;#13;&amp;#10; }&amp;#13;&amp;#10; div2.style.width = wid2 + 'px';&amp;#13;&amp;#10; div2.style.height = hei2 + 'px';&amp;#13;&amp;#10;&amp;#13;&amp;#10; itv2 = setTimeout(animate2, INTERVAL2);&amp;#13;&amp;#10; }&amp;#13;&amp;#10;&amp;#13;&amp;#10; window.onload = function() {&amp;#13;&amp;#10; cv1 = document.getElementById('cv1');&amp;#13;&amp;#10; div2 = document.getElementById('div2');&amp;#13;&amp;#10; ck1 = document.getElementById('ck1');&amp;#13;&amp;#10; ck2 = document.getElementById('ck2');&amp;#13;&amp;#10;&amp;#13;&amp;#10; ck1['onchange'] = function() {&amp;#13;&amp;#10; if (ck1.checked)&amp;#13;&amp;#10; itv1 = setInterval(animate1, INTERVAL1);&amp;#13;&amp;#10; else&amp;#13;&amp;#10; clearInterval(itv1);&amp;#13;&amp;#10; };&amp;#13;&amp;#10; ck2['onchange'] = function() {&amp;#13;&amp;#10; if (ck2.checked)&amp;#13;&amp;#10; itv2 = setTimeout(animate2, INTERVAL2);&amp;#13;&amp;#10; else&amp;#13;&amp;#10; clearTimeout(itv2);&amp;#13;&amp;#10; };&amp;#13;&amp;#10;&amp;#13;&amp;#10; wid2 = hei2 = 1;&amp;#13;&amp;#10; x = 1;&amp;#13;&amp;#10; ctx = cv1.getContext(&amp;quot;2d&amp;quot;);&amp;#13;&amp;#10; ctx.fillStyle = &amp;quot;rgba(0,0,200,0.6)&amp;quot;;&amp;#13;&amp;#10; ck1['onchange']();&amp;#13;&amp;#10; ck2['onchange']();&amp;#13;&amp;#10; }&amp;#13;&amp;#10; &amp;lt;/script&amp;gt;&amp;#13;&amp;#10;&amp;lt;/head&amp;gt;&amp;#13;&amp;#10;&amp;lt;body&amp;gt;&amp;#13;&amp;#10; &amp;lt;div&amp;gt;&amp;#13;&amp;#10; &amp;lt;input id='ck1' type='checkbox' checked='checked' /&amp;gt;&amp;lt;label for=&amp;quot;ck1&amp;quot;&amp;gt;enable Animation 1&amp;lt;/label&amp;gt;&amp;#13;&amp;#10; &amp;lt;input id='ck2' type='checkbox' checked='checked' /&amp;gt;&amp;lt;label for=&amp;quot;ck2&amp;quot;&amp;gt;enable Animation 2&amp;lt;/label&amp;gt;&amp;#13;&amp;#10; &amp;lt;/div&amp;gt;&amp;#13;&amp;#10; &amp;lt;canvas id=&amp;quot;cv1&amp;quot; width=&amp;quot;800&amp;quot; height=&amp;quot;100&amp;quot; style=&amp;quot;background-color: Lime; margin-top:20px;&amp;quot;&amp;gt;Your browser does not support Canvas&amp;lt;/canvas&amp;gt;&amp;#13;&amp;#10; &amp;lt;div id='div2' style=&amp;quot;background-color:Olive; position: relative; width:100px; height:100px; margin-top:20px; border: 1px solid black;&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/div&amp;gt;&amp;#13;&amp;#10;&amp;lt;/body&amp;gt;&amp;#13;&amp;#10;&amp;lt;/html&amp;gt;&lt;/textarea&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span lang="EN-US"&gt;Some Librarys:&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://jqapi.com/#p=animate"&gt;http://jqapi.com/#p=animate&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://jljlpch.iteye.com/blog/234130"&gt;jquery animate&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="https://github.com/JeffreyZhao/jscex"&gt;https://github.com/JeffreyZhao/jscex&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&#xD;
         &lt;a href="http://www.sndacode.com/projects/jscex/wiki"&gt;http://www.sndacode.com/projects/jscex/wiki&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&#xD;
         &lt;a href="http://files.zhaojie.me/jscex/samples/async/move.html"&gt;move.html&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&#xD;
         &lt;a href="http://files.zhaojie.me/jscex/samples/async/sorting-animations.html"&gt; sorting-animations.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.infoq.com/articles/surviving-asynchronous-programming-in-javascript"&gt; http://www.infoq.com/articles/surviving-asynchronous-programming-in-javascript&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.neilmix.com/narrativejs/doc/"&gt;http://www.neilmix.com/narrativejs/doc/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.infoq.com/articles/stratifiedjs"&gt;http://www.infoq.com/articles/stratifiedjs&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;span lang="EN-US" style='font-size: 10.5pt; font-family: "Calibri","sans-serif"'&gt;&lt;br clear="all" style='page-break-before: always' /&gt;&#xD;
         &lt;/span&gt;&#xD;
         &lt;p  align="left" style='text-align: left'&gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p&gt;&lt;strong&gt;&lt;a name="_Toc309058916"&gt;&lt;span lang="EN-US"&gt;Js class, &amp;#8216;&lt;em&gt;delegate&lt;/em&gt;&amp;#8217; &amp;amp; Inheritance&lt;/span&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span lang="EN-US"&gt;Codes:&lt;a href='#' onclick="javascript:doc = window.open().document; doc.write(document.getElementById('txt4').value); doc.close(); return false;"&gt;Run&lt;/a&gt;&lt;textarea id='txt4' rows="30" cols="90"&gt;&amp;lt;html&amp;gt;&amp;#13;&amp;#10;&amp;lt;head&amp;gt;&amp;#13;&amp;#10; &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;#13;&amp;#10; // class definition&amp;#13;&amp;#10; function Person(name,gender, age) {&amp;#13;&amp;#10; this.name = name;&amp;#13;&amp;#10; this.gender = gender;&amp;#13;&amp;#10; this.age = age;&amp;#13;&amp;#10;&amp;#13;&amp;#10; this.speak = function() {&amp;#13;&amp;#10; log('this is ' + this.name + ' speaking.');&amp;#13;&amp;#10; }&amp;#13;&amp;#10; }&amp;#13;&amp;#10; Person.prototype.toString = function() {&amp;#13;&amp;#10; return this.name + '(age:' + this.gender + '),' + this.age;&amp;#13;&amp;#10; }&amp;#13;&amp;#10; Person.Parse = function(s) { //static method&amp;#13;&amp;#10; try{&amp;#13;&amp;#10; var ary = s.split(',');&amp;#13;&amp;#10; return new Person(ary[0], ary[1], ary[2]);&amp;#13;&amp;#10; }catch(e){&amp;#13;&amp;#10; return null;&amp;#13;&amp;#10; }&amp;#13;&amp;#10; }&amp;#13;&amp;#10;&amp;#13;&amp;#10; //method use function as argument&amp;#13;&amp;#10; function revealObject(obj, fn) {&amp;#13;&amp;#10; var aryInfo = [];&amp;#13;&amp;#10; for (var k in obj) {&amp;#13;&amp;#10; var s = fn(k, obj[k]);&amp;#13;&amp;#10; if (!s) continue;&amp;#13;&amp;#10; aryInfo.push(s);&amp;#13;&amp;#10; }&amp;#13;&amp;#10; return aryInfo.join('\r\n');&amp;#13;&amp;#10; }&amp;#13;&amp;#10;&amp;#13;&amp;#10; //inheritance&amp;#13;&amp;#10; function Programer(n, g, a, lan) {&amp;#13;&amp;#10; Person.call(this, n, g, a);&amp;#13;&amp;#10; //Person.apply(this, [n, g, a]);&amp;#13;&amp;#10;&amp;#13;&amp;#10; this.language = lan;&amp;#13;&amp;#10; }&amp;#13;&amp;#10; Programer.prototype = new Person;&amp;#13;&amp;#10; Programer.prototype.toString = function() {&amp;#13;&amp;#10; return Person.prototype.toString.call(this) + ' , ' + this.language;&amp;#13;&amp;#10; }&amp;#13;&amp;#10;&amp;#13;&amp;#10; function log(s) {&amp;#13;&amp;#10; document.getElementById('tOutput').value += (s ? s : '') + '\r\n';&amp;#13;&amp;#10; }&amp;#13;&amp;#10;&amp;#13;&amp;#10; window.onload = function() {&amp;#13;&amp;#10; log('class demo\r\n-------------------------------');&amp;#13;&amp;#10; var p1 = new Person('bill', 16, 'male');&amp;#13;&amp;#10; var p2 = Person.Parse('steve,48,male');&amp;#13;&amp;#10; log(p1 + '\r\n' + p2);&amp;#13;&amp;#10; p1.speak();&amp;#13;&amp;#10; p2.speak();&amp;#13;&amp;#10;&amp;#13;&amp;#10; log('\r\ndelegate demo\r\n-------------------------------');&amp;#13;&amp;#10; var f1 = function(s1, s2) { return s1 + ' : ' + s2; };&amp;#13;&amp;#10; var s1 = revealObject(p1, f1);&amp;#13;&amp;#10; log(s1);&amp;#13;&amp;#10; log();&amp;#13;&amp;#10; var s2 = revealObject(p2, function(s1, s2) { if (typeof (s2) == 'function') return ''; return s1 + ',' + s2; });&amp;#13;&amp;#10; log(s2);&amp;#13;&amp;#10;&amp;#13;&amp;#10; log('\r\ninheritance demo\r\n-------------------------------');&amp;#13;&amp;#10; var pg1 = new Programer('kate', 'female', 22, 'C, C++');&amp;#13;&amp;#10; log(pg1);&amp;#13;&amp;#10; }&amp;#13;&amp;#10; &amp;lt;/script&amp;gt;&amp;#13;&amp;#10;&amp;lt;/head&amp;gt;&amp;#13;&amp;#10;&amp;lt;body&amp;gt;&amp;#13;&amp;#10; &amp;lt;textarea id='tOutput' rows='30' cols='90'&amp;gt;&amp;lt;/textarea&amp;gt;&amp;#13;&amp;#10;&amp;lt;/body&amp;gt;&amp;#13;&amp;#10;&amp;lt;/html&amp;gt;&lt;/textarea&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://www.joelonsoftware.com/items/2006/08/01.html"&gt;http://www.joelonsoftware.com/items/2006/08/01.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://mckoss.com/jscript/object.htm"&gt;http://mckoss.com/jscript/object.htm&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://ejohn.org/blog/simple-javascript-inheritance/"&gt;http://ejohn.org/blog/simple-javascript-inheritance/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&lt;a href="http://odetocode.com/blogs/scott/archive/2007/07/05/function-apply-and-function-call-in-javascript.aspx"&gt; http://odetocode.com/blogs/scott/archive/2007/07/05/function-apply-and-function-call-in-javascript.aspx&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;p &gt;&lt;span lang="EN-US"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
         &lt;/div&gt;&#xD;
     &lt;/body&gt;&#xD;
&lt;/html&gt;&#xD;
&lt;img src="http://www.cnblogs.com/michael-zhang/aggbug/2309431.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/michael-zhang/archive/2012/01/01/2309431.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/michael-zhang/archive/2011/07/08/2101031.html</id><title type="text">Concatenating row values in Transact-SQL</title><summary type="text">转自: http://www.projectdmx.com/tsql/rowconcatenate.aspx Concatenating row values in Transact-SQL Introduction A core issue Considerations Concatenating values when the number of items is small and known upfront Concatenating values when the number of items are not known Recursive CTE method The black</summary><published>2011-07-08T07:16:00Z</published><updated>2011-07-08T07:16:00Z</updated><author><name>lin-zhang</name><uri>http://www.cnblogs.com/michael-zhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/michael-zhang/archive/2011/07/08/2101031.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/michael-zhang/archive/2011/07/08/2101031.html"/><content type="html">&lt;p&gt;&lt;strong&gt;转自&lt;/strong&gt;: &lt;a href="http://www.projectdmx.com/tsql/rowconcatenate.aspx"&gt;http://www.projectdmx.com/tsql/rowconcatenate.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;table width="100%" cellpadding="0" cellspacing="0" border="0"&gt;&#xD;
     &lt;tbody&gt;&#xD;
         &lt;tr valign="top"&gt;&#xD;
             &lt;td align="center" style="width: 100px"&gt;&lt;/td&gt;&#xD;
             &lt;td align="center"&gt;&#xD;
             &lt;table &gt;&#xD;
                 &lt;tbody&gt;&#xD;
                     &lt;tr align="left"&gt;&#xD;
                         &lt;td valign="top"&gt;&lt;strong&gt;Concatenating row values in Transact-SQL&lt;/strong&gt;&lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;/td&gt;&#xD;
                     &lt;/tr&gt;&#xD;
                     &lt;tr align="left"&gt;&#xD;
                         &lt;td valign="top"&gt;&lt;strong&gt;&#xD;
                         &lt;ul type="disc"&gt;&#xD;
                             &lt;li&gt;&lt;a href="#Intro"&gt;Introduction&lt;/a&gt;&lt;/li&gt;&#xD;
                             &lt;li&gt;&lt;a href="#Core"&gt;A core issue&lt;/a&gt;&lt;/li&gt;&#xD;
                             &lt;li&gt;&lt;a href="#Consider"&gt;Considerations&lt;/a&gt;&lt;/li&gt;&#xD;
                             &lt;li&gt;&lt;a href="#Limited"&gt;Concatenating values when the number of items is small and known upfront&lt;/a&gt;&lt;/li&gt;&#xD;
                             &lt;li&gt;&lt;a href="#Unlimited"&gt;Concatenating values when the number of items are not known&lt;/a&gt;&lt;/li&gt;&#xD;
                             &lt;ul type="square"&gt;&#xD;
                                 &lt;li&gt;&lt;a href="#RecurCTE"&gt;Recursive CTE method&lt;/a&gt;&lt;/li&gt;&#xD;
                                 &lt;li&gt;&lt;a href="#BBXML"&gt;The blackbox XML methods&lt;/a&gt;&lt;/li&gt;&#xD;
                                 &lt;li&gt;&lt;a href="#UsingCLR"&gt;Using Common Language Runtime&lt;/a&gt;&lt;/li&gt;&#xD;
                                 &lt;li&gt;&lt;a href="#ScalarRecur"&gt;Scalar UDF with recursion&lt;/a&gt;&lt;/li&gt;&#xD;
                                 &lt;li&gt;&lt;a href="#TblUDF"&gt;Table valued UDF with a WHILE loop&lt;/a&gt;&lt;/li&gt;&#xD;
                                 &lt;li&gt;&lt;a href="#DynamicSQL"&gt;Dynamic SQL&lt;/a&gt;&lt;/li&gt;&#xD;
                                 &lt;li&gt;&lt;a href="#Cursor"&gt;The Cursor approach&lt;/a&gt;&lt;/li&gt;&#xD;
                             &lt;/ul&gt;&#xD;
                             &lt;li&gt;&lt;a href="#Unreliable"&gt;Non-reliable approaches&lt;/a&gt;&lt;/li&gt;&#xD;
                             &lt;ul type="square"&gt;&#xD;
                                 &lt;li&gt;&lt;a href="#UpdateExtn"&gt;Scalar UDF with t-SQL update extension&lt;/a&gt;&lt;/li&gt;&#xD;
                                 &lt;li&gt;&lt;a href="#SelectConcat"&gt;Scalar UDF with variable concatenation in SELECT&lt;/a&gt;&lt;/li&gt;&#xD;
                             &lt;/ul&gt;&#xD;
                             &lt;li&gt;&lt;a href="#Concl"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;&#xD;
                             &lt;li&gt;&lt;a href="#Refer"&gt;References&lt;/a&gt;&lt;/li&gt;&#xD;
                             &lt;li&gt;&lt;a href="#Acknow"&gt;Acknowledgements&lt;/a&gt;&lt;/li&gt;&#xD;
                         &lt;/ul&gt;&#xD;
                         &lt;/strong&gt;&lt;/td&gt;&#xD;
                     &lt;/tr&gt;&#xD;
                     &lt;tr&gt;&#xD;
                         &lt;td align="left"&gt;&lt;strong&gt;&lt;a name="#Intro"&gt;&lt;/a&gt;Introduction&lt;/strong&gt;&lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         Many a time, SQL programmers are faced with a requirement to generate report-like resultsets right off of a Transact SQL&#xD;
                         query. In most cases, the requirement arises from the fact that there are no sufficient tools or in-house expertise to develop&#xD;
                         tools that can extract the data as a resultset and massage the data in the desired display format. Quite often folks are&#xD;
                         confused about the potential of breaking relational fundamentals say like First Normal Form or the scalar nature of typed&#xD;
                         values. (Talking about 1NF violations in a language like SQL which lacks sufficient domain support, allows NULLs and supports&#xD;
                         duplicates is somewhat ironic to begin with, but that is a topic which requires detailed explanations.)&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         Concatenating column values or expressions from multiple rows are usually best done in a client side application language,&#xD;
                         since the string manipulation capabilities of Transact SQL and SQL based DBMSs are somewhat limited. However, you can do these&#xD;
                         using different approaches in Transact SQL, but avoiding such methods for long term solutions is your best bet.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#Core"&gt;&lt;/a&gt;A core issue&lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         Even though SQL in general deviates considerably from the relational model, its reliance on certain core aspects of relational&#xD;
                         foundations makes SQL functional and powerful. One such core aspect is the set based nature of SQL expressions (well, multi-sets&#xD;
                         to be exact, but for the given context let us ignore the issue of duplication). The primary idea is that tables are unordered&#xD;
                         and hence the resultsets of any query that does not have an explicit ORDER BY clause is unordered as well. In other words, the rows&#xD;
                         in a resultset of a query do not have a prescribed position, unless it is explicitly specified in the query expression.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         On the other hand, a concatenated list is an ordered structure. Each element in the list has a specific position. In fact,&#xD;
                         concatenation itself is an order-utilizing operation in the sense that values can be prefixed or post fixed to an existing list. So&#xD;
                         approaches that are loosely called &amp;#8220;concatenating row values&amp;#8221;, &amp;#8220;aggregate concatenation&amp;#8221; etc. would have to make sure that some kind&#xD;
                         of an order, either explicit or implicit, should be specified prior to concatenating the row values. If such an ordering criteria&#xD;
                         is not provided, the concatenated string would be arbitrary in nature.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#Consider"&gt;&lt;/a&gt;Considerations&lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         Generally, requests for row value concatenations often comes in two basic flavors, when the number of rows is known and small (typically&#xD;
                         less than 10) and when the number of rows is unknown and potentially large. It may be better to look at each of them separately.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         In some cases, all the programmer wants is just the list of values from a set of rows. There is no grouping or logical partitioning&#xD;
                         of values like the list of email addresses separated by a semicolon or some such. In such situations, the approaches can be the same&#xD;
                         except the join conditions may vary. Minor variations of the examples list on this page illustrate such solutions as well.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         For the purpose of this article the Products table from Northwind database is used to illustrate column value concatenations with a&#xD;
                         grouping column. Northwind is a sample database in SQL Server 2000 default installations. You can download a copy from from the&#xD;
                         &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=06616212-0356-46a0-8da2-eebc53a68034&amp;amp;displaylang=en"&gt;Microsoft Downloads&lt;/a&gt;&#xD;
                         Consider the resultset produced by the following query:&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;pre&gt;SELECT CategoryId, ProductName&#xD;
                         FROM Northwind..Products ;&#xD;
                         CategoryId ProductName&#xD;
                         ----------- ----------------------------------------&#xD;
                         1 Chai&#xD;
                         1 Chang&#xD;
                         ...&#xD;
                         2 Aniseed Syrup&#xD;
                         2 Chef Anton's Cajun Seasoning&#xD;
                         ...&#xD;
                         ...&#xD;
                         8 Spegesild&#xD;
                         (77 row(s) affected)&#xD;
                         &lt;/pre&gt;&#xD;
                         The goal is to return a resultset with two columns one with the Category Identifier and the other with a concatenated list of all&#xD;
                         the Product Names separated by a delimiting character, say a comma for instance.&#xD;
                         &lt;pre&gt;CategoryId Product List&#xD;
                         ----------- -----------------------------------------------------------------------------&#xD;
                         1 Chai, Chang, Chartreuse verte, C&amp;#244;te de Blaye, ...&#xD;
                         2 Aniseed Syrup, Chef Anton's Cajun Seasoning, ...&#xD;
                         3 Chocolade, Gumb&amp;#228;r Gummib&amp;#228;rchen, Maxilaku, ...&#xD;
                         4 Camembert Pierrot, Flotemysost, Geitost, Gorgonzola Telino, ...&#xD;
                         5 Filo Mix, Gnocchi di nonna Alice, Gustaf's Kn&amp;#228;ckebr&amp;#246;d, ...&#xD;
                         6 Alice Mutton, Mishi Kobe Niku, P&amp;#226;t&amp;#233; chinois, ...&#xD;
                         7 Longlife Tofu, Manjimup Dried Apples, R&amp;#246;ssle Sauerkraut, ...&#xD;
                         8 Boston Crab Meat, Carnarvon Tigers, Escargots de Bourgogne, ...&#xD;
                         (8 row(s) affected)&#xD;
                         &lt;/pre&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#Limited"&gt;&lt;/a&gt;Concatenating values when the number of items is small and known upfront&lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         When the number of rows are small and almost known upfront, it is easier to generate the code. One common approach with a small set&#xD;
                         of finite rows it the pivoting method. Here is an example where only first four alphabetically sorted product names per categoryid is&#xD;
                         retrieved:&#xD;
                         &lt;pre&gt;SELECT CategoryId,&#xD;
                         MAX( CASE seq WHEN 1 THEN ProductName ELSE '' END ) + ', ' +&#xD;
                         MAX( CASE seq WHEN 2 THEN ProductName ELSE '' END ) + ', ' +&#xD;
                         MAX( CASE seq WHEN 3 THEN ProductName ELSE '' END ) + ', ' +&#xD;
                         MAX( CASE seq WHEN 4 THEN ProductName ELSE '' END )&#xD;
                         FROM ( SELECT p1.CategoryId, p1.ProductName,&#xD;
                         ( SELECT COUNT(*)&#xD;
                         FROM Northwind.dbo.Products p2&#xD;
                         WHERE p2.CategoryId = p1.CategoryId&#xD;
                         AND p2.ProductName &amp;lt;= p1.ProductName )&#xD;
                         FROM Northwind.dbo.Products p1 ) D ( CategoryId, ProductName, seq )&#xD;
                         GROUP BY CategoryId ;&#xD;
                         &lt;/pre&gt;&#xD;
                         The idea above is to create a expression inside the correlated subquery that produces a rank (seq) based on the product names and&#xD;
                         then use it in the outer query. Using common table expressions and the ROW_NUMBER() function, you can re-write this as:&#xD;
                         &lt;pre&gt;; WITH CTE ( CategoryId, ProductName, seq )&#xD;
                         AS ( SELECT p1.CategoryId, p1.ProductName,&#xD;
                         ROW_NUMBER() OVER ( PARTITION BY CategoryId ORDER BY ProductName )&#xD;
                         FROM Northwind.dbo.Products p1 )&#xD;
                         SELECT CategoryId,&#xD;
                         MAX( CASE seq WHEN 1 THEN ProductName ELSE '' END ) + ', ' +&#xD;
                         MAX( CASE seq WHEN 2 THEN ProductName ELSE '' END ) + ', ' +&#xD;
                         MAX( CASE seq WHEN 3 THEN ProductName ELSE '' END ) + ', ' +&#xD;
                         MAX( CASE seq WHEN 4 THEN ProductName ELSE '' END )&#xD;
                         FROM CTE&#xD;
                         GROUP BY CategoryId ;&#xD;
                         &lt;/pre&gt;&#xD;
                         Note that ROW_NUMBER() is a newly introduced feature in SQL 2005. If you are using any previous versions, you will have to use the&#xD;
                         subquery approach (You can also use a self-join, to write it a bit differently). Using the recently introduced PIVOT operator, you&#xD;
                         can write the above as following :&#xD;
                         &lt;pre&gt;SELECT CategoryId,&#xD;
                         "1" + ', ' + "2" + ', ' + "3" + ', ' + "4" AS Product_List&#xD;
                         FROM ( SELECT CategoryId, ProductName,&#xD;
                         ROW_NUMBER() OVER (PARTITION BY CategoryId ORDER BY ProductName)&#xD;
                         FROM Northwind.dbo.Products ) P ( CategoryId, ProductName, seq )&#xD;
                         PIVOT ( MAX( ProductName ) FOR seq IN ( "1", "2", "3", "4" ) ) AS P_ ;&#xD;
                         &lt;/pre&gt;&#xD;
                         Not only the syntax appears a bit confusing, it does not appear to offer anything functionally beyond the CASE approach above. However,&#xD;
                         in rare situations, it could come in handy.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#Unlimited"&gt;&lt;/a&gt;Concatenating values when the number of items is not known &lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         When the number of items that are to be concatenated is not known upfront, the code can become a bit more demanding. The new features&#xD;
                         in SQL 2005 make some of the approaches a bit easy. For instance, the recursive common table expressions (CTEs) and the FOR XML PATH('')&#xD;
                         syntax makes the server do the hard work behind the concatenation leaving the programmer to deal with the presentation issues. The&#xD;
                         examples below make this point obvious.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#RecurCTE"&gt;&lt;/a&gt;Recursive CTE methods &lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         The idea behind this method is from a newsgroup posting by Vadim Tropashko similar to the ideas behind generating a materialized path&#xD;
                         for hierarchies.&#xD;
                         &lt;pre&gt;WITH CTE ( CategoryId, product_list, product_name, length )&#xD;
                         AS ( SELECT CategoryId, CAST( '' AS VARCHAR(8000) ), CAST( '' AS VARCHAR(8000) ), 0&#xD;
                         FROM Northwind..Products&#xD;
                         GROUP BY CategoryId&#xD;
                         UNION ALL&#xD;
                         SELECT p.CategoryId, CAST( product_list +&#xD;
                         CASE WHEN length = 0 THEN '' ELSE ', ' END + ProductName AS VARCHAR(8000) ),&#xD;
                         CAST( ProductName AS VARCHAR(8000)), length + 1&#xD;
                         FROM CTE c&#xD;
                         INNER JOIN Northwind..Products p&#xD;
                         ON c.CategoryId = p.CategoryId&#xD;
                         WHERE p.ProductName &amp;gt; c.product_name )&#xD;
                         SELECT CategoryId, product_list&#xD;
                         FROM ( SELECT CategoryId, product_list,&#xD;
                         RANK() OVER ( PARTITION BY CategoryId ORDER BY length DESC )&#xD;
                         FROM CTE ) D ( CategoryId, product_list, rank )&#xD;
                         WHERE rank = 1 ;&#xD;
                         &lt;/pre&gt;&#xD;
                         The CASE in the recursive part of the CTE is used to eliminate the initial comma and you can use RIGHT or the SUBSTRING functions&#xD;
                         to substitute it. Also, this may not be the best performing option, however certain additional tuning could be done to make them&#xD;
                         suitable for medium sized datasets.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         Another approach using recursive common table expressions was sent in by Anub Philip, an Engineer from Sathyam Computers that uses&#xD;
                         separate common table expressions for the anchor and recursive parts.&#xD;
                         &lt;pre&gt;WITH Ranked ( CategoryId, rnk, ProductName )&#xD;
                         AS ( SELECT CategoryId,&#xD;
                         ROW_NUMBER() OVER( PARTITION BY CategoryId ORDER BY CategoryId ),&#xD;
                         CAST( ProductName AS VARCHAR(8000) )&#xD;
                         FROM Northwind..Products),&#xD;
                         AnchorRanked ( CategoryId, rnk, ProductName )&#xD;
                         AS ( SELECT CategoryId, rnk, ProductName&#xD;
                         FROM Ranked&#xD;
                         WHERE rnk = 1 ),&#xD;
                         RecurRanked ( CategoryId, rnk, ProductName )&#xD;
                         AS ( SELECT CategoryId, rnk, ProductName&#xD;
                         FROM AnchorRanked&#xD;
                         UNION ALL&#xD;
                         SELECT Ranked.CategoryId, Ranked.rnk,&#xD;
                         RecurRanked.ProductName + ', ' + Ranked.ProductName&#xD;
                         FROM Ranked&#xD;
                         INNER JOIN RecurRanked&#xD;
                         ON Ranked.CategoryId = RecurRanked.CategoryId&#xD;
                         AND Ranked.rnk = RecurRanked.rnk + 1 )&#xD;
                         SELECT CategoryId, MAX( ProductName )&#xD;
                         FROM RecurRanked&#xD;
                         GROUP BY CategoryId;&#xD;
                         &lt;/pre&gt;&#xD;
                         On an initial glance, this query may seem a bit expensive in comparison, however the reader is encouraged check the execution plans and&#xD;
                         make any additional tweaks as needed.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#BBXML"&gt;&lt;/a&gt;The blackbox XML methods&lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         An example for string concatenation using FOR XML clause with PATH mode is detailed below. It was initially posted by Eugene Kogan&#xD;
                         later became common in public newsgroups.&#xD;
                         &lt;pre&gt;SELECT p1.CategoryId,&#xD;
                         ( SELECT ProductName + ','&#xD;
                         FROM Northwind.dbo.Products p2&#xD;
                         WHERE p2.CategoryId = p1.CategoryId&#xD;
                         ORDER BY ProductName&#xD;
                         FOR XML PATH('') ) AS Products&#xD;
                         FROM Northwind.dbo.Products p1&#xD;
                         GROUP BY CategoryId ;&#xD;
                         &lt;/pre&gt;&#xD;
                         Again, the similar approach originally found in the beta newsgroups, using CROSS APPLY operator.&#xD;
                         &lt;pre&gt;SELECT DISTINCT CategoryId, ProductNames&#xD;
                         FROM Products p1&#xD;
                         CROSS APPLY ( SELECT ProductName + ','&#xD;
                         FROM Products p2&#xD;
                         WHERE p2.CategoryId = p1.CategoryId&#xD;
                         ORDER BY ProductName&#xD;
                         FOR XML PATH('') ) D ( ProductNames )&#xD;
                         &lt;/pre&gt;&#xD;
                         You may notice a comma at the end of the concatenated string, which you can remove using a STUFF, SUBSTRING or LEFT function. While the&#xD;
                         above methods are deemed reliable by many at the time of writing, there is no guarantee that it will stay that way given the internal&#xD;
                         workings and evaluation rules of FOR XML PATH() expression in correlated subqueries are not well documented.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#UsingCLR"&gt;&lt;/a&gt;Using Common Language Runtime&lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         Though this article is about approaches using Transact SQL, this section is included due to the popularity of CLR aggregates in SQL 2005. Not only it&#xD;
                         empowers the CLR programmer with new options for database development, in some cases, they work at least as well as native Transact&#xD;
                         SQL approaches.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         If you are familiar with .NET languages, SQL 2005 offers a convenient way to create user defined aggregate functions using C#, VB.NET or&#xD;
                         similar languages that is supported by the Common Language Runtime (CLR). Here is an example of a string concatenate aggregate function&#xD;
                         written using C#.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;pre&gt;using System;&#xD;
                         using System.Collections.Generic;&#xD;
                         using System.Data.SqlTypes;&#xD;
                         using System.IO;&#xD;
                         using Microsoft.SqlServer.Server;&#xD;
                         [Serializable]&#xD;
                         [SqlUserDefinedAggregate(Format.UserDefined, MaxByteSize=8000)]&#xD;
                         public struct strconcat : IBinarySerialize{&#xD;
                         private List&lt;string&gt; values;&#xD;
                         public void Init() {&#xD;
                         this.values = new List&lt;string&gt;();&#xD;
                         }&#xD;
                         public void Accumulate(SqlString value) {&#xD;
                         this.values.Add(value.Value);&#xD;
                         }&#xD;
                         public void Merge(strconcat value) {&#xD;
                         this.values.AddRange(value.values.ToArray());&#xD;
                         }&#xD;
                         public SqlString Terminate() {&#xD;
                         return new SqlString(string.Join(", ", this.values.ToArray()));&#xD;
                         }&#xD;
                         public void Read(BinaryReader r) {&#xD;
                         int itemCount = r.ReadInt32();&#xD;
                         this.values = new List&lt;string&gt;(itemCount);&#xD;
                         for (int i = 0; i &amp;lt;= itemCount - 1; i++) {&#xD;
                         this.values.Add(r.ReadString());&#xD;
                         }&#xD;
                         }&#xD;
                         public void Write(BinaryWriter w) {&#xD;
                         w.Write(this.values.Count);&#xD;
                         foreach (string s in this.values) {&#xD;
                         w.Write(s);&#xD;
                         }&#xD;
                         }&#xD;
                         }&#xD;
                         &lt;/string&gt;&lt;/string&gt;&lt;/string&gt;&lt;/pre&gt;&#xD;
                         Once you build and deploy this assembly on the server, you should be able to execute your concatenation query as:&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;pre&gt;SELECT CategoryId,&#xD;
                         dbo.strconcat(ProductName)&#xD;
                         FROM Products&#xD;
                         GROUP BY CategoryId ;&#xD;
                         &lt;/pre&gt;&#xD;
                         If you are a total newbie on CLR languages, and would like to learn more about developing database solutions using CLR languages,&#xD;
                         consider starting at &lt;a href="http://msdn2.microsoft.com/en-us/library/ms131089.aspx"&gt;Introduction to Common Language Runtime (CLR)&#xD;
                         Integration&lt;/a&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#ScalarRecur"&gt;&lt;/a&gt;Scalar UDF with recursion &lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         Recursive functions in t-SQL have a drawback that the maximum nesting level is 32. So this approach is applicable only for smaller&#xD;
                         datasets, especially when the number of items within a group, that needs to be concatenated, is less than 32.&#xD;
                         &lt;pre&gt;CREATE FUNCTION udf_recursive ( @cid INT, @i INT )&#xD;
                         RETURNS VARCHAR(8000) AS BEGIN&#xD;
                         DECLARE @r VARCHAR(8000), @l VARCHAR(8000)&#xD;
                         SELECT @i = @i - 1, @r = ProductName + ', '&#xD;
                         FROM Products p1&#xD;
                         WHERE CategoryId = @cid&#xD;
                         AND @i = ( SELECT COUNT(*) FROM Products p2&#xD;
                         WHERE p2.CategoryId = p1.CategoryId&#xD;
                         AND p2.ProductName &amp;lt;= p1.ProductName ) ;&#xD;
                         IF @i &amp;gt; 0 BEGIN&#xD;
                         EXEC @l = dbo.udf_recursive @cid, @i ;&#xD;
                         SET @r = @l + @r ;&#xD;
                         END&#xD;
                         RETURN @r ;&#xD;
                         END&#xD;
                         &lt;/pre&gt;&#xD;
                         This function can be invoked as follows:&#xD;
                         &lt;pre&gt;SELECT CategoryId,&#xD;
                         dbo.udf_recursive( CategoryId, COUNT(ProductName) )&#xD;
                         FROM Products&#xD;
                         GROUP BY CategoryId ;&#xD;
                         &lt;/pre&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#TblUDF"&gt;&lt;/a&gt;Table valued UDF with a WHILE loop &lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         This approach is based on the idea by Linda Wierzbecki where a table variable with three columns is used within a table valued UDF.&#xD;
                         The first column represents the group, second represents the currently processing value within a group and the third represents the&#xD;
                         concatenated list of values.&#xD;
                         &lt;pre&gt;CREATE FUNCTION udf_tbl_Concat() RETURNS @t TABLE(&#xD;
                         CategoryId INT,&#xD;
                         Product VARCHAR(40),&#xD;
                         list VARCHAR(8000) )&#xD;
                         BEGIN&#xD;
                         INSERT @t (CategoryId, Product, list)&#xD;
                         SELECT CategoryId, MIN(ProductName), MIN(ProductName)&#xD;
                         FROM Products&#xD;
                         GROUP BY CategoryId&#xD;
                         WHILE ( SELECT COUNT(Product) FROM @t ) &amp;gt; 0 BEGIN&#xD;
                         UPDATE t&#xD;
                         SET list = list + COALESCE(&#xD;
                         ( SELECT ', ' + MIN( ProductName )&#xD;
                         FROM Products&#xD;
                         WHERE Products.CategoryId = t.CategoryId&#xD;
                         AND Products.ProductName &amp;gt; t.Product), ''),&#xD;
                         Product = ( SELECT MIN(ProductName)&#xD;
                         FROM Products&#xD;
                         WHERE Products.CategoryId = t.CategoryId&#xD;
                         AND Products.ProductName &amp;gt; t.Product )&#xD;
                         FROM @t t END&#xD;
                         RETURN&#xD;
                         END&#xD;
                         &lt;/pre&gt;&#xD;
                         The usage of the above function can be like:&#xD;
                         &lt;pre&gt;SELECT CategoryId, list AS Products&#xD;
                         FROM udf_tbl_Concat() ;&#xD;
                         &lt;/pre&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#DynamicSQL"&gt;&lt;/a&gt;Dynamic SQL&lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         This approach is a variation of the kludge often known using the nickname as dynamic cross tabulation.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         This approach is a variation of the kludge often known using the nickname as dynamic cross tabulation. There is enough literature out&#xD;
                         there which demonstrates the drawbacks and implications of using Dynamic SQL. A popular one, at least from Transact SQL programmer&amp;#8217;s&#xD;
                         perspective, is Erland's &lt;a href="http://www.sommarskog.se/dynamic_sql.html"&gt;Curse and Blessings of Dynamic SQL.&lt;/a&gt; The Dynamic SQL&#xD;
                         approaches can be developed based on creating a Transact SQL query string based on the number of groups and then use a series of CASE&#xD;
                         expressions or ROW_NUMBER() function to pivot the data for concatenation.&#xD;
                         &lt;pre&gt;DECLARE @r VARCHAR(MAX), @n INT, @i INT&#xD;
                         SELECT @i = 1,&#xD;
                         @r = 'SELECT CategoryId, ' + CHAR(13),&#xD;
                         @n = (SELECT TOP 1 COUNT( ProductName )&#xD;
                         FROM Products&#xD;
                         GROUP BY CategoryId&#xD;
                         ORDER BY COUNT( ProductName ) DESC ) ;&#xD;
                         WHILE @i &amp;lt;= @n BEGIN&#xD;
                         SET @r = @r +&#xD;
                         CASE WHEN @i = 1&#xD;
                         THEN 'MAX( CASE Seq WHEN ' + CAST( @i AS VARCHAR ) + '&#xD;
                         THEN ProductName&#xD;
                         ELSE SPACE(0) END ) + ' + CHAR(13)&#xD;
                         WHEN @i = @n&#xD;
                         THEN 'MAX( CASE Seq WHEN ' + CAST( @i AS VARCHAR ) + '&#xD;
                         THEN '', '' + ProductName&#xD;
                         ELSE SPACE(0) END ) ' + CHAR(13)&#xD;
                         ELSE 'MAX( CASE Seq WHEN ' + CAST( @i AS VARCHAR ) + '&#xD;
                         THEN '', '' + ProductName&#xD;
                         ELSE SPACE(0) END ) + ' + CHAR(13)&#xD;
                         END ;&#xD;
                         SET @i = @i + 1 ;&#xD;
                         END&#xD;
                         SET @r = @r + '&#xD;
                         FROM ( SELECT CategoryId, ProductName,&#xD;
                         ROW_NUMBER() OVER ( PARTITION BY CategoryId ORDER BY ProductName )&#xD;
                         FROM Products p ) D ( CategoryId, ProductName, Seq )&#xD;
                         GROUP BY CategoryId;'&#xD;
                         EXEC( @r ) ;&#xD;
                         &lt;/pre&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#Cursor"&gt;&lt;/a&gt;The Cursor approach&lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         The drawbacks of rampant usage of cursors are well-known among the Transact SQL community. Given the fact that they are generally&#xD;
                         resource intensive, procedural and inefficient, one should strive to avoid cursors or loop based solutions in general Transact SQL&#xD;
                         programming.&#xD;
                         &lt;pre&gt;DECLARE @tbl TABLE (id INT PRIMARY KEY, list VARCHAR(8000))&#xD;
                         SET NOCOUNT ON&#xD;
                         DECLARE @c INT, @p VARCHAR(8000), @cNext INT, @pNext VARCHAR(40)&#xD;
                         DECLARE c CURSOR FOR&#xD;
                         SELECT CategoryId, ProductName&#xD;
                         FROM Products&#xD;
                         ORDER BY CategoryId, ProductName ;&#xD;
                         OPEN c ;&#xD;
                         FETCH NEXT FROM c INTO @cNext, @pNext ;&#xD;
                         SET @c = @cNext ;&#xD;
                         WHILE @@FETCH_STATUS = 0 BEGIN&#xD;
                         IF @cNext &amp;gt; @c BEGIN&#xD;
                         INSERT @tbl SELECT @c, @p ;&#xD;
                         SELECT @p = @PNext, @c = @cNext ;&#xD;
                         END ELSE&#xD;
                         SET @p = COALESCE(@p + ',', SPACE(0)) + @pNext ;&#xD;
                         FETCH NEXT FROM c INTO @cNext, @pNext&#xD;
                         END&#xD;
                         INSERT @tbl SELECT @c, @p ;&#xD;
                         CLOSE c ;&#xD;
                         DEALLOCATE c ;&#xD;
                         SELECT * FROM @tbl ;&#xD;
                         &lt;/pre&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#Unreliable"&gt;&lt;/a&gt;Non-reliable approaches&lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         This section details a couple of notorious methods often publicized by some in public forums. The problem with these methods is that&#xD;
                         they rely on the physical implementation model; changes in indexes, statistics etc or even a change of a simple expression in the&#xD;
                         SELECT list or ORDER BY clause can change the output. Also these are undocumented, unsupported and unreliable to the point where one&#xD;
                         can consistently demonstrate failures. Therefore these methods are not at all recommended for production mode systems.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#UpdateExtn"&gt;&lt;/a&gt;Scalar UDF with t-SQL update extension &lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         The usage of an expression that involves a column, a variable and an expression in the SET clause in an UPDATE statement rarely appear&#xD;
                         intuitive. However, in general, the optimizer often seems to process these values in the order of materialization, either in the internal&#xD;
                         work tables or any other storage structures.&#xD;
                         &lt;pre&gt;CREATE FUNCTION udf_update_concat (@CategoryId INT)&#xD;
                         RETURNS VARCHAR(MAX) AS&#xD;
                         BEGIN&#xD;
                         DECLARE @t TABLE(p VARCHAR(40));&#xD;
                         DECLARE @r VARCHAR(MAX) ;&#xD;
                         SET @r = SPACE(0) ;&#xD;
                         INSERT @t ( p ) SELECT ProductName FROM Products&#xD;
                         WHERE CategoryId = @CategoryId ;&#xD;
                         IF @@ROWCOUNT &amp;gt; 0&#xD;
                         UPDATE @t&#xD;
                         SET @r = @r + p + ',' ;&#xD;
                         RETURN(@r)&#xD;
                         END&#xD;
                         &lt;/pre&gt;&#xD;
                         Here is how to use this function:&#xD;
                         &lt;pre&gt;SELECT CategoryId, dbo.udf_update_concat(CategoryId)&#xD;
                         FROM Products&#xD;
                         GROUP BY CategoryId ;&#xD;
                         &lt;/pre&gt;&#xD;
                         Again, it is important to consider that lack of physical independence that is being exploited here before using or recommending this as&#xD;
                         a usable and meaningful solution.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#SelectConcat"&gt;&lt;/a&gt;Scalar UDF with variable concatenation in SELECT &lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         This is an approachpurely dependent on the physical implementation and internal access paths. Before using this approach, make sure to&#xD;
                         refer to the &lt;a href="http://support.microsoft.com/default.aspx/kb/287515"&gt;relevant knowledgebase article&lt;/a&gt;.&#xD;
                         &lt;pre&gt;CREATE FUNCTION dbo.udf_select_concat ( @c INT )&#xD;
                         RETURNS VARCHAR(MAX) AS BEGIN&#xD;
                         DECLARE @p VARCHAR(MAX) ;&#xD;
                         SET @p = '' ;&#xD;
                         SELECT @p = @p + ProductName + ','&#xD;
                         FROM Products&#xD;
                         WHERE CategoryId = @c ;&#xD;
                         RETURN @p&#xD;
                         END&#xD;
                         &lt;/pre&gt;&#xD;
                         And, as for its usage:&#xD;
                         &lt;pre&gt;SELECT CategoryId, dbo.udf_select_concat( CategoryId )&#xD;
                         FROM Products&#xD;
                         GROUP BY CategoryId ;&#xD;
                         &lt;/pre&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#Concl"&gt;&lt;/a&gt;Conclusion&lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         Regardless of how it is used, "aggregate concatenation" of row values in Transact SQL, especially when there is a grouping, is not&#xD;
                         a simple routine. Various programming considerations are to be carefully considered to choose one method over another depending on&#xD;
                         the situations. The most logical choice would be the availability of a built-in operator with optional configurable parameters that&#xD;
                         can do the concatenation of the values depending on the type. Till then, reporting requirements and external data export routines&#xD;
                         will have to rely on such Transact SQL programming hacks.&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#Refer"&gt;&lt;/a&gt;References&lt;/strong&gt;&#xD;
                         &lt;ul&gt;&#xD;
                             &lt;li&gt;&lt;a href="http://support.microsoft.com/default.aspx/kb/287515"&gt;PRB: Execution Plan and Results of Aggregate Concatenation&#xD;
                             Queries Depend Upon Expression Location&lt;/a&gt;&lt;/li&gt;&#xD;
                             &lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=06616212-0356-46a0-8da2-eebc53a68034&amp;amp;displaylang=en"&gt;Northwind and pubs&#xD;
                             Sample Databases for SQL Server 2000&lt;/a&gt;&lt;/li&gt;&#xD;
                             &lt;li&gt;&lt;a href="http://www.sommarskog.se/dynamic_sql.html"&gt;The Curse and Blessings of Dynamic SQL&lt;/a&gt;&lt;/li&gt;&#xD;
                             &lt;li&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ms131089.aspx"&gt;Introduction to Common Language Runtime (CLR) Integration&lt;/a&gt;&lt;/li&gt;&#xD;
                         &lt;/ul&gt;&#xD;
                         &lt;strong&gt;&lt;a name="#Acknow"&gt;&lt;/a&gt;Acknowledgements&lt;/strong&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         &lt;br /&gt;&#xD;
                         Umachandar Jayachandran, Linda Wierzbecki, Bruce Margolin, Roy Harvey, Eugene Kogan, Vadim Tropashko, Anub Philip.&#xD;
                         &lt;/td&gt;&#xD;
                     &lt;/tr&gt;&#xD;
                 &lt;/tbody&gt;&#xD;
             &lt;/table&gt;&#xD;
             &lt;/td&gt;&#xD;
             &lt;td align="center" style="width: 100px"&gt;&lt;/td&gt;&#xD;
         &lt;/tr&gt;&#xD;
     &lt;/tbody&gt;&#xD;
&lt;/table&gt;&lt;img src="http://www.cnblogs.com/michael-zhang/aggbug/2101031.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/michael-zhang/archive/2011/07/08/2101031.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/michael-zhang/archive/2008/11/24/1339918.html</id><title type="text">silverlight小游戏:　贪吃蛇</title><summary type="text">发布个好玩的小游戏 ;) 有兴趣的在此下载源码.有点小问题:1, silverlight中没有Invoke方法, 用BeginInvoke更新UI时, 设置速度值为30以内刷新会出问题, 不知道有什么解决办法没 ;(2, 附源码中有个winForm版的, 每次是重绘Panel对象的几个小方块内容; 试过缓存bitmap, 重绘整个panel的方式, 好像屏幕更闪了; 不知道专业的小游戏是采取哪种方...</summary><published>2008-11-24T07:51:00Z</published><updated>2008-11-24T07:51:00Z</updated><author><name>lin-zhang</name><uri>http://www.cnblogs.com/michael-zhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/michael-zhang/archive/2008/11/24/1339918.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/michael-zhang/archive/2008/11/24/1339918.html"/></entry><entry><id>http://www.cnblogs.com/michael-zhang/archive/2007/02/17/651831.html</id><title type="text">SharpPad文本编辑器: 已完成添加代码自动完成、代码折叠等功能</title><summary type="text">SharpDevelop分析系列已写到第四篇 SharpDevelop浅析_4_TextEditor_自动完成、代码折叠……  ,  至此已基本补充完整 SharpPad的功能，与第三篇中的 Demo 相比，增加了代码自动完成、代码折叠、类/成员 快速定位等功能&#xD;&#xD;访问此处(http://www.cnblogs.com/michael-zhang/articles/651825.html) 以查看详情</summary><published>2007-02-16T17:45:00Z</published><updated>2007-02-16T17:45:00Z</updated><author><name>lin-zhang</name><uri>http://www.cnblogs.com/michael-zhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/michael-zhang/archive/2007/02/17/651831.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/michael-zhang/archive/2007/02/17/651831.html"/></entry><entry><id>http://www.cnblogs.com/michael-zhang/archive/2007/02/01/636387.html</id><title type="text">SharpDevelop浅析_3_Internationalization-TextEditor __ 读书心得</title><summary type="text">首先，庆贺下自己的"SharpDevelop浅析_3_Internationalization-TextEditor分析文章"在一周的艰苦努力中终于写了出来&#xD;&#xD;在这一周读代码的学习过程中颇有些感受，总结起来有以下几点收获：&#xD;坚持、自信：  上周末看了电子书的相关章节，然后读代码，周末两天的时间看下来仍是一头雾水，接下来的三天中也仍是有许多困惑，有时会想工作的事不少，下班还要搞这个分析，而且又公开在博客上了还给自己定时间争取年底前完成整个SharpDevelop分析，这不自找麻烦。但是坚持下来写出读书心得时便会庆幸自己坚持了下来。&#xD;&#xD;跳过细节、总体把握： 读代码时遇到许多不清楚的，如果想在一周内把每个细节都搞清楚时间上肯定不够，而且现在想想也不符合学习规律，只要在不影响全局理解的情况下，重点要先对整个事情有个全局的把握，然后一步步细化，看感兴趣的具体细节实现。&#xD;&#xD;要会提问题：  对事物/项目的了解要在有一定的认识后不断的提出问题、找答案，在这个过程中才会有更深的理解，如果提不出问题，只是一味地读代码，相信到现在我也分析不出个头绪。&#xD;</summary><published>2007-01-31T19:43:00Z</published><updated>2007-01-31T19:43:00Z</updated><author><name>lin-zhang</name><uri>http://www.cnblogs.com/michael-zhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/michael-zhang/archive/2007/02/01/636387.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/michael-zhang/archive/2007/02/01/636387.html"/></entry><entry><id>http://www.cnblogs.com/michael-zhang/archive/2007/01/25/629739.html</id><title type="text">SharpDevelop代码分析</title><summary type="text">最近在作.NET的C/S项目，由于经验比较少，便想通过读《Dissecting a C# Application Inside SharpDevelop》结合SharpDevelop源码的学习，全面地了解一下好的应用程序是如何编写的，从中不但能锻炼编程能力，也可以进行一些架构的思考。&#xD;到现在已写了两篇读后感文章，好像没被其他人看到过，便写了这篇随笔放在首页，希望大家园子里的朋友多支持下，多多评论、交流 :-)&#xD;SharpDevelop分析（http://www.cnblogs.com/michael-zhang/category/82115.html）&#xD;SharpDevelop浅析_序 （http://www.cnblogs.com/michael-zhang/articles/621144.html）</summary><published>2007-01-24T16:19:00Z</published><updated>2007-01-24T16:19:00Z</updated><author><name>lin-zhang</name><uri>http://www.cnblogs.com/michael-zhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/michael-zhang/archive/2007/01/25/629739.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/michael-zhang/archive/2007/01/25/629739.html"/></entry><entry><id>http://www.cnblogs.com/michael-zhang/archive/2007/01/15/621201.html</id><title type="text">博客开张了</title><summary type="text">工作中的项目感觉锻炼不大，业余随便看点什么又总是水过无痕，于是写博客吧。&#xD;在沦浪之水的QQ群(26227899)中看到公告提醒大家写年度计划，长远的我也计划不了，暂定近一两个月读《Dissecting a C# Application Inside SharpDevelop》写读后感吧，没写过博客，刚花了几个小时发贴子，满头大汗终于把文章发出去了，效果也不是很满意，慢慢来吧。  欢迎园子里的朋友多评论、多交流 :-) </summary><published>2007-01-15T15:28:00Z</published><updated>2007-01-15T15:28:00Z</updated><author><name>lin-zhang</name><uri>http://www.cnblogs.com/michael-zhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/michael-zhang/archive/2007/01/15/621201.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/michael-zhang/archive/2007/01/15/621201.html"/></entry></feed>
