<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
  <channel>
    <title><![CDATA[rank's technical notes]]></title> 
    <link>http://www.never-online.net/blog/</link> 
    <description><![CDATA[A crisis is a terrible thing to waste.]]></description> 
    <language>en</language> 
    <copyright><![CDATA[Copyright 2012, rank's technical notes]]></copyright> 
    <webMaster><![CDATA[blueDestiny[at]126.com (never-online)]]></webMaster> 
    <generator>LBS v2.0.304</generator> 
    <pubDate>Sun, 05 Feb 2012 04:35:23 +0800</pubDate> 
    <ttl>60</ttl>
  
    <item>
      <title><![CDATA[webkit里会出现突然闪一下的问题]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=323]]></link> 
      <category><![CDATA[开发日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Thu, 05 Jan 2012 14:00:03 +0800</pubDate> 
      <description><![CDATA[写这么多的字比较累，看得也累，如果想直接知道解决方法，就一句：<div class="code" id="codeFragment1">-webkit-backface-visibility: hidden; <br />（但不能用于sprite雪碧图）<br /><br />或者<br />.no-flick{-webkit-transform:translate3d(0,0,0);}</div><br />一，场景<br />在chrome下出现屏幕会闪，但不是每次都能复现。<br />出现这类问题，是种头疼的事。<br /><br />二，初步debug<br />昨天晚上和maomao，晓刚我提起，会否是我们的mask导致。<br />因为mask的style是加了opacity。没有加display:none。页面还没load就把mask给加到body第一个元素了。<br /><br />而后我在mask把background:white改成Red。看看是否会闪成红色。<br />很遗憾是没有出现红色。<br />结论基本确定不是mask导致的问题。<br /><br />但幸运的是发现这个问题相起来都是在header处，并且是在&lt;a &gt;&lt;i&gt;&lt;i&gt;&lt;/a&gt;标签里。<br /><br />三，再次debug<br />第二天中午吃饭的时候说起今天一定要想法解决这个问题。<br />晓亮提到会否是Transform引起的。<br />于是下午试了一下，去除transform果然管用。<br />但是我们仍然没有知道解决办法，以及为何这样。<br /><br />晚上回到家之后再打开dom inspect。先精简代码（如果没法定位问题，精简代码也可以采取二分法，这样速度理论上会更快些）：<div class="code" id="codeFragment2">&lt;!doctype html&gt;<br />&lt;!--STATUS OK--&gt;<br />&lt;html&gt;<br />&lt;head&gt;<br />&nbsp;&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=gb2312&quot; /&gt;<br />&nbsp;&lt;link href=&quot;http&#58;//st.youa.com/resource/css/apps/sns_bc.css?f98dcf15fd.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen&quot;&gt;<br />&nbsp;&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;http&#58;//st.youa.com/resource/sp/sns/home/css/index.css?1325074239.css&quot;/&gt;<br />&lt;/head&gt;<br />&lt;body&gt;<br />&lt;div id=&quot;header&quot;&gt;<br />&nbsp;&lt;div class=&quot;global-header&quot;&gt;<br />&nbsp;&lt;div class=&quot;global-header-inner&quot;&gt;<br />&nbsp;&lt;ul class=&quot;person&quot;&gt;<br />&nbsp;&lt;li class=&quot;top-user&quot; id=&quot;top-user&quot;&gt;&lt;a href=&quot;###&quot; class=&quot;user&quot;&gt;&lt;img src=&#39;<br />&nbsp;http&#58;//img.youa.com/img_new/a94813a8f57f526b715f5c2a--20-20-1&#39; alt=&quot;&quot;/&gt;rank&lt;i&gt;&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;<br />&nbsp;&lt;li class=&quot;top-mess&quot; id=&quot;top-mess&quot;&gt;&lt;a href=&quot;javascript:;&quot; class=&quot;mess&quot;&gt;消息&lt;i&gt;&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;<br />&nbsp;&lt;/ul&gt;<br />&nbsp;<br />&nbsp;&lt;/div&gt;<br />&nbsp;&lt;/div&gt;<br />&lt;/div&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;</div><br />四，解决问题<br />在百度上搜索类似css 3 transform bug，无果。<br />别灰心，在stackoverflow上看看。<br />query: &quot;transform flick bug webkit&quot;<br />果然有料。<br /><a href="http://stackoverflow.com/questions/3461441/prevent-flicker-on-webkit-transition-of-webkit-transform" title="http://stackoverflow.com/questions/3461441/prevent-flicker-on-webkit-transition-of-webkit-transform" target="_blank">http://stackoverflow.com/questions/3461441/prevent-flicker-on-webkit-transition-of-webkit-transform</a><br /><br />五，是否还有其他优化方案<br />意味着在i元素里也加入<br />-webkit-backface-visibility: hidden; <br />（但不能用于sprite雪碧图）<br /><br />也可以通过<br />.no-flick{-webkit-transform:translate3d(0,0,0);}<br />来解决。<br /><br />直观上看，我看到translate3d这么解决，心里想这不是扯东窗补西窗么。<br />顺着往下看，果然如此。translate3d有问题。<div class="quote"><div class="quote-title">引用 <u></u></div><div class="quote-content">However, the body {-webkit-transform} approach causes all elements on the page to effectively be rendered in 3D. This isn&#39;t the worst thing, but it slightly changes the rendering of text and other CSS-styled elements.<br />It may be an effect you want. It may be useful if you&#39;re doing a lot of transform on your page. Otherwise, -webkit-backface-visibility:hidden on the element your transforming is the least invasive option.</div></div>所以， 从目前来看-webkit-backface-visibility: hidden; 是最优解。<br /><br />六，弄清源头<br />关于这个css3属性拿来作什么用的。可以查阅w3c<br /><a href="http://www.w3.org/TR/css3-3d-transforms/#backface-visibility-property" title="http://www.w3.org/TR/css3-3d-transforms/#backface-visibility-property" target="_blank">http://www.w3.org/TR/css3-3d-transforms/#backface-visibility-property</a><div class="quote"><div class="quote-title">引用 <u></u></div><div class="quote-content">The ‘backface-visibility’ property determines whether or not the &quot;back&quot; side of a transformed element is visible when facing the viewer. With an identity transform, the front side of an element faces the viewer. Applying a rotation about Y of 180 degrees (for instance) would cause the back side of the element to face the viewer.<br />This property is useful when you place two elements back-to-back, as you would to create a playing card. Without this property, the front and back elements could switch places at times during an animation to flip the card. Another example is creating a box out of 6 elements, but where you want to see the inside faces of the box. This is useful when creating the backdrop for a 3 dimensional stage.</div></div>也就是说这个属性做翻卡片的小游戏，比较合适哈。<br />测试运行以下代码，就能理解为什么会在transform时会闪：<div class="code" id="codeFragment3">&lt;!DOCTYPE HTML&gt;<br />&lt;html&gt;<br />&lt;head&gt;<br />&lt;style type=&quot;text/css&quot;&gt; <br />#div1 {<br />width:120px;<br />height:100px;<br />background-color:yellow;<br />border:1px solid black;<br />-moz-transform:rotateY(25deg); /* Firefox */<br />-webkit-transform:rotateY(25deg); /* Safari and Chrome */<br />transform:rotateY(25deg);<br />}<br />&lt;/style&gt;<br />&lt;script type=&quot;text/javascript&quot;&gt;<br />function rotate(value) {<br />&nbsp;&nbsp;document.getElementById(&#39;div1&#39;).style.webkitTransform = &quot;rotateY(&quot; + value + &quot;deg)&quot;;<br />&nbsp;&nbsp;document.getElementById(&#39;div1&#39;).style.MozTransform = &quot;rotateY(&quot; + value + &quot;deg)&quot;;<br />&nbsp;&nbsp;document.getElementById(&#39;div1&#39;).style.transform = &quot;rotateY(&quot; + value + &quot;deg)&quot;;<br />&nbsp;&nbsp;document.getElementById(&#39;span1&#39;).innerHTML = value + &quot;deg&quot;<br />}<br />function checkBackface() {<br />&nbsp;&nbsp;if (document.getElementById(&quot;bf&quot;).checked == true) {<br />&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(&#39;div1&#39;).style.webkitBackfaceVisibility = &quot;hidden&quot;<br />&nbsp;&nbsp;} else {<br />&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(&#39;div1&#39;).style.webkitBackfaceVisibility = &quot;visible&quot;<br />&nbsp;&nbsp;}<br />}<br />&lt;/script&gt;<br />&lt;/head&gt;<br />&lt;body&gt;<br />&lt;div id=&quot;div1&quot;&gt;HELLO&lt;/div&gt;<br />&lt;p&gt;Rotate the yellow div element, with and without checking the backface-visibility checkbox:&lt;/p&gt;<br />&lt;p&gt;Hide the backside:&lt;input type=&quot;checkbox&quot; onchange=&quot;checkBackface()&quot; id=&quot;bf&quot; /&gt;&lt;/p&gt;<br />Rotate:&lt;br /&gt;<br />&lt;input type=&quot;range&quot; min=&quot;-360&quot; max=&quot;360&quot; value=&quot;25&quot; onchange=&quot;rotate(this.value)&quot; /&gt;&lt;br /&gt;<br />-webkit-transform: rotateY(&lt;span id=&quot;span1&quot;&gt;7deg&lt;/span&gt;);<br />&lt;/body&gt;<br />&lt;/html&gt;</div>我的理解是transform其实都是3维的变换，而backface-visibility:hidden，则是在几个面隐藏。理论上解释得通，合情合理。<br />如上，如果把translate3d变换关闭也可，但性能不好。<br />如。象border:0与border:none是有本质区别的。<br />0需要浏览器渲染。而none不需要渲染。<br /><br />结论<br />在用position:absulote+zindex!=0时用transform会偶尔出现页面会闪的现象，确实是chrome的一个bug。<br />chromium里没有发现有人提bug，所以我检索了一下webkit.org的bugtrace，看到<br /><a href="https://bugs.webkit.org/show_bug.cgi?id=47175" title="https://bugs.webkit.org/show_bug.cgi?id=47175" target="_blank">https://bugs.webkit.org/show_bug.cgi?id=47175</a><br /><a href="https://bug-47175-attachments.webkit.org/attachment.cgi?id=69779" title="https://bug-47175-attachments.webkit.org/attachment.cgi?id=69779" target="_blank">https://bug-47175-attachments.webkit.org/attachment.cgi?id=69779</a><br />这哥们儿还举出case了。就不用自己写bad case了。<br />-webkit-backface-visibility: hidden; 是最优解。<br /><br />OK。结案。]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=323]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[云标签，关键字图排版 html5 canvas版（一）]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=322]]></link> 
      <category><![CDATA[开发日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Mon, 19 Dec 2011 20:58:19 +0800</pubDate> 
      <description><![CDATA[最近业余时间在做一个云标签相关的信息展现. 大概做成的情况能像微博关键字一样形成这样的图形:<br /><div style="width: 100%;overflow-x : auto;"><a href="http://ww1.sinaimg.cn/bmiddle/62d43e17jw1dmsag98kaaj.jpg" target="_blank" rel="lightbox"><img src="http://ww1.sinaimg.cn/bmiddle/62d43e17jw1dmsag98kaaj.jpg" alt="http://ww1.sinaimg.cn/bmiddle/62d43e17jw1dmsag98kaaj.jpg" class="imgBorder"/></a></div><br /><br />在做的过程当中,查阅了一些资料, 发现自己有点out了,在国外已经在wordle.net这样的网站.<br />也有一个叫做信息视觉化(Information Visualization)的概念.于是顺着这个概念再googling了一些相关的知识.把一些知识点做一下笔记.<br /><br />Information Visualization<br />漂亮,惊艳.与传统的云标签的表现力对比,原来的太普通了.给人全新的一种视觉感受.<br />而后我的想法则是为什么这么有表现力的技术不能用在我们现在的项目上?所以我有了去尝试做这种排版的想法.<br />现在把一些过程记录,给自己的一种笔记,给其他后来者留下一些资料.<br />而云标签只是信息视觉化的其中一个很小的应用.有兴趣的同学可以参考wiki或我文后给出的链接查看详情.<br />这里不展开描述，不是本文的重点。<br /><br />过程<br />以上图为例,一句话简单的描述起来就是,不停的尝试把当前的文字放到能够放到的位置,直到没有文字为止.<br />稍微画个流程图的话,大致如下:<br /><div style="width: 100%;overflow-x : auto;"><a href="http://www.never-online.net/blog/uploads/201012/workflow.png" target="_blank" rel="lightbox"><img src="http://www.never-online.net/blog/uploads/201012/workflow.png" alt="http://www.never-online.net/blog/uploads/201012/workflow.png" class="imgBorder"/></a></div><br /><br />这里面需要特别说明的几点, 各位可以先试想一下这几个问题:<br />1.如何进行字符碰撞检测?<br />2.如果是在脚本里去做的话,如何能拿到文字显示到画布上的像素点?<br />3.文字大小如何设定?<br />4.文字是垂直还是水平如何设定?<br />5.如果我要显示特殊图形如何扩展?<br /><br />---------分隔线--------<br /><br />1.碰撞检测是很耗CPU的.最笨的方法是每个像素点都去遍历尝试,直到能放到区域内为止.也可以用空间换时间,例如使用hash cache降低放在canvas中的io操作.再进一步可以把目前所有文字的范围最小x,y坐标,最大的x,y坐标记录下来,以便于下次检测碰撞可以直接限制坐标范围.<br />2.canvas目前高版本里可以用canvas.getContext(&#39;2d&#39;).measureText(word).width(注:目前也仅支持这一个属性,其他属性还不支持)<br />3.文字大小设置最大值, 设: 最大值==出现最多字的count,那么比例ratio=MaxFontsize/maxWordcount,随之过滤掉过小的fontsize字.<br />4.文字和水平对于排版影响不大,可在随机,也可以通过一个函数是做符合设定规则的转换,如查用随机显示文字是垂直还是水平简单一句:isVertical = Math.random &gt; 0.3;<br />5.特殊图形==图形显示范围.我个人理解应该至少有两种方案,一种是用函数计算出来,另一种方案是先手工把边界制定出来,而后再填充.(本质上是一样去约束范围)<br /><br />关键代码<br />1.文字count<br />如果是中文的话,需要处理分词,分好词后再count. 关于中文分词已经算是一个单独领域了, 我不专业,就此跳过. 而英文的话很好办.<br />words = text.split(/\b/);<br />直接通过边界分,然后转成map,count后用filter过滤即可.<br />比较简单,代码略过.<br /><br />2.范围<br />如何能让文字随机显示在界面上呢?<div class="code" id="codeFragment1">function normalInt(min, max, iter) {<br />&nbsp;var arr = []; for(var i=0; i&lt;iter; i++) arr.push(Math.random());<br />&nbsp;return Math.floor(arr.reduce(function (i, j) {return i + j}, 0) / iter * (max - min)) + min;<br />}</div>iter值越大,得出的结果越接近于min, max的中间值.<br />以Math.random()随机范围在(0~1),如果随机次数趋向正无穷,那么理论上随机的平均值是趋向于0.5.<br />例: normalInt(0,100,10000),结果接近于50,有可能出现的结果是49.12334<br />所以,如果代码是<div class="code" id="codeFragment2">var x = normalInt(0, canvas.width, 100),<br />&nbsp;&nbsp;y = normalInt(0, canvas.height, 100);</div>理论上,将正态分布在画布的中心周围.<br /><br />3.如何能得到显示文字边缘<br />canvas里面能获得imagedata, 获取CanvasPixelArray接口为canvas.getContext(&#39;2d&#39;).getImageData(x, y, width, height);<br />数据类型为CanvasPixelArray. 它是像素矩阵的扁平表示方法:<br /><div style="width: 100%;overflow-x : auto;"><a href="http://www.never-online.net/blog/uploads/201012/img_1308366650_5.jpg" target="_blank" rel="lightbox"><img src="http://www.never-online.net/blog/uploads/201012/img_1308366650_5.jpg" alt="http://www.never-online.net/blog/uploads/201012/img_1308366650_5.jpg" class="imgBorder"/></a></div><br /><br />CanvasPixelArray包括 宽*高*4 个字节的数据, 索引范围从0到 (高*宽*4)-1.<br />要取得图片里一个[x,y]坐标的red颜色信息可以用以下方法<br />var redValueForPixel = ((y - 1) * (width * 4)) + ((x - 1) * 4);<br /><div style="width: 100%;overflow-x : auto;"><a href="http://www.never-online.net/blog/uploads/201012/img_1308366651_6.jpg" target="_blank" rel="lightbox"><img src="http://www.never-online.net/blog/uploads/201012/img_1308366651_6.jpg" alt="http://www.never-online.net/blog/uploads/201012/img_1308366651_6.jpg" class="imgBorder"/></a></div><br /><br />另:在处理图像的时候,如果有API可用的话,基本都是按这样的索引结构存储.<br /><div class="code" id="codeFragment3">&lt;h1&gt;点击图片的rgba信息并将body background显示为该色&lt;/h1&gt;<br />&lt;p&gt;&lt;strong&gt;load 外部图权限需要提升&lt;/strong&gt;&lt;/p&gt;<br />&lt;script type=&quot;text/javascript&quot; src=&quot;http&#58;//code.jquery.com/jquery-1.7.1.min.js&quot;&gt;&lt;/script&gt;<br />&lt;script type=&quot;text/javascript&quot;&gt;<br />onload = function() {<br />&nbsp;&nbsp;var cx, canvas;<br />&nbsp;&nbsp;var WIDTH = 280, HEIGHT = 140;<br />&nbsp;&nbsp;var image = new Image();<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;void function createCanvas() {<br />&nbsp;&nbsp;&nbsp;&nbsp;canvas = document.createElement(&#39;canvas&#39;);<br />&nbsp;&nbsp;&nbsp;&nbsp;canvas.width  = WIDTH;<br />&nbsp;&nbsp;&nbsp;&nbsp;canvas.height = HEIGHT;<br />&nbsp;&nbsp;&nbsp;&nbsp;canvas.style.border = &#39;1px solid #000&#39;;<br />&nbsp;&nbsp;&nbsp;&nbsp;document.body.appendChild(canvas);<br />&nbsp;&nbsp;&nbsp;&nbsp;cx = canvas.getContext(&#39;2d&#39;);<br />&nbsp;&nbsp;}();<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;void function loadImage() {<br />&nbsp;&nbsp;&nbsp;&nbsp;image.src = &quot;http&#58;//www.baidu.com/img/baidu_sylogo1.gif&quot;;<br />&nbsp;&nbsp;&nbsp;&nbsp;$(image).load(function() {<br />&nbsp;&nbsp;&nbsp;&nbsp;    cx.drawImage(image, 0, 0);<br />&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;}();<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;$(canvas).click(function(e) {<br />&nbsp;&nbsp;    var canvasOffset = $(canvas).offset();<br />&nbsp;&nbsp;    var canvasX = Math.floor(e.pageX-canvasOffset.left);<br />&nbsp;&nbsp;    var canvasY = Math.floor(e.pageY-canvasOffset.top);<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;try {<br />&nbsp;&nbsp;    &nbsp;&nbsp;var imageData = cx.getImageData(0, 0, canvas.width, canvas.height);<br />&nbsp;&nbsp;    } catch(ex) {<br />&nbsp;&nbsp;&nbsp;&nbsp;    netscape.security.PrivilegeManager.enablePrivilege(&quot;UniversalBrowserRead&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;    var imageData = cx.getImageData(0, 0, canvas.width, canvas.height);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;    <br />&nbsp;&nbsp;    var pixels = imageData.data;<br />&nbsp;&nbsp;    var pixelRedIndex = ((canvasY - 1) * (imageData.width * 4)) + ((canvasX - 1) * 4);<br />&nbsp;&nbsp;    var pixelcolor = &quot;rgba(&quot;+pixels[pixelRedIndex]+&quot;, &quot;+pixels[pixelRedIndex+1]+&quot;, &quot;+pixels[pixelRedIndex+2]+&quot;, &quot;+pixels[pixelRedIndex+3]+&quot;)&quot;;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;    $(&quot;body&quot;).css(&quot;backgroundColor&quot;, pixelcolor);<br />&nbsp;&nbsp;});<br />}<br />&lt;/script&gt;</div><br />4.碰撞<br />碰撞的算法比较简单,但是如何能提高碰撞检测的效率是关键之处.<br />这里用的方法是通过基于绘制文本的x,y为基础点去做判断.复杂度为循环要绘制文本的像素点:<br />O(((y - 1) * (width * 4)) + ((x - 1) * 4));<br />近似等于O( (Math.max(width, height)^2) ).<div class="code" id="codeFragment4">/**<br />&nbsp;* collusion 检测碰撞<br />&nbsp;* @param  {CanvasPixelArray} imageData 画布的imageData<br />&nbsp;* @param  {CanvasPixelArray} wordImageData 文字的imageData<br />&nbsp;* @param  {Number} x 绘制文字在画布的x坐标<br />&nbsp;* @param  {Number} y 绘制文字在画布的y坐标<br />&nbsp;* @return {Boolean} 返回是否碰撞<br />&nbsp;*/<br />function collision(imageData, wordImageData, x, y) {<br />&nbsp;var wdata, fdata, wy, widx, widxend, fidx, wv, fv;<br /><br />&nbsp;wdata = wordImageData.data;<br />&nbsp;fdata = imageData.data;<br /><br />&nbsp;for (wy = wordImageData.height - 1; wy &gt;= 0; --wy) {<br />&nbsp;&nbsp;//逐行扫描<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;widx = wy * wordimg.width * 4;//当前行rgba起始值<br />&nbsp;&nbsp;&nbsp;&nbsp;widxend = widx + (wordimg.width * 4);//当前行末rgba结束值<br /><br />&nbsp;fidx = ((y + wy) * imageData.width + x) * 4;//大画布中当前行的像素起始值<br />&nbsp;for (; widx &lt; widxend; widx += 4, fidx += 4) {//根据wordimg+y坐标定位到行,开始逐列扫描,并进行比较<br /><br />&nbsp;//因为rgba的rgb任意像素都可能为空,所以只用判断opacity<br />&nbsp;wv = wdata[widx + 3];<br />&nbsp;fv = fdata[fidx + 3];<br /><br />&nbsp;//需要放置的文字在某个坐标透明度不为零<br />&nbsp;//及在已存在画布上坐标上透明度也不为零,即为碰撞<br />&nbsp;if (wv &amp;&amp; fv) return true;<br />&nbsp;}<br />&nbsp;}<br />&nbsp;return false;<br />}</div><br />一些资料<br />CanvasPixelArray参考MDC<br /><a href="https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas" title="https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas" target="_blank">https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas</a><br /><br />wordle.net的作者写的一些资料:<br /><a href="http://static.mrfeinberg.com/bv_ch03.pdf" title="http://static.mrfeinberg.com/bv_ch03.pdf" target="_blank">http://static.mrfeinberg.com/bv_ch03.pdf</a><br /><br />信息可视化wiki:<br /><a href="http://en.wikipedia.org/wiki/Information_visualization" title="http://en.wikipedia.org/wiki/Information_visualization" target="_blank">http://en.wikipedia.org/wiki/Information_visualization</a><br /><br />stackoverflow上的一些信息:<br /><a href="http://stackoverflow.com/questions/342687/algorithm-to-implement-a-word-cloud-like-wordle" title="http://stackoverflow.com/questions/342687/algorithm-to-implement-a-word-cloud-like-wordle" target="_blank">http://stackoverflow.com/questions/342687/algorithm-to-implement-a-word-cloud-like-wordle</a>]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=322]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[javascript的configuration/interface变换]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=321]]></link> 
      <category><![CDATA[开发日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Tue, 29 Nov 2011 17:28:05 +0800</pubDate> 
      <description><![CDATA[问题<br />1.例如我们常遇到的兼容问题, 请尝试写一个Style.get(element, &#39;opacity&#39;)方法.<br />是不是该在Style.get里实现加入if是IE.而且&lt;10之类的判断.<br />2.focusin,onmouseenter,onmouseleave事件,使得业务调用可以使用及绑定这些事件.<br />3.链式调用.<br /><br />这样的例子可以拿出很多, 其实要说用中间层处理dom分支, 在很早的dom框架里Base2就经常看到.<br />在base2里经常可以看到@ie, @mozilla之类的字符串, 其实也是conf配置,中间函数分发的一种.<br /><br />如果不是针对dom编程,而是针对有一套规则,中间层针对规则去做处理,或许就能更好编程. <br />以下几段代码算是抛砖引玉,也许大家都有更好的思路.<br /><br />解决方法<br />示例1, css兼容<br />看使用方法,cssconf配置,来看看property以及读写器的配置规则<div class="code" id="codeFragment1">//尝试一种针对标准配置的方式<br />//取值潜规则<br />//1.对应在map中浏览器中修正的属性值<br />//2.修正的读写器（一定要为函数）<br />//2.配置map中浏览器对应的default值<br />//3.最后用传参过来的默认值<br />//为不同浏览器配置属性的hash<br />//如果是纯属性值结构为<br />//&#39;property&#39;: {<br />//&nbsp;&nbsp;&#39;browser&#39;: &#39;property-value&#39;<br />//&nbsp;&nbsp;&#39;default&#39;: &#39;default-value&#39;<br />//}<br />//如果是读写器函数，结构为<br />//&#39;property&#39;: {<br />//&nbsp;&nbsp;&#39;browser&#39;: {<br />//&nbsp;&nbsp;&nbsp;&nbsp;set: function(el, css, value) {}<br />//&nbsp;&nbsp;&nbsp;&nbsp;get: function(el, css, value) {}<br />//&nbsp;&nbsp;}<br />//}<br />var cssconf = {<br />&nbsp;&nbsp;&#39;transition&#39;: {<br />&nbsp;&nbsp;&nbsp;&nbsp;&#39;ie&#39;     : &#39;-ms-transition&#39;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&#39;webkit&#39; : &#39;-webkit-transition&#39;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&#39;firefox&#39;: &#39;-moz-transition&#39;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&#39;opera&#39;  : &#39;-o-transition&#39;<br />&nbsp;&nbsp;},<br />&nbsp;&nbsp;&#39;float&#39;   : { &#39;default&#39;: &#39;cssFloat&#39; },<br />&nbsp;&nbsp;&#39;opacity&#39; : {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;ie&#39; : {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set: function(el, css, value) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = parseFloat(value) || 1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var styleObject = el.style;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//如果设置的透明度为1时，IE里去除alpha通道的滤镜<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var result = (1 != value) ? &#39;alpha(opacity=&#39; +(value*100)+ &#39;)&#39; : &#39;&#39;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;styleObject.filter = (styleObject.filter||&#39;&#39;).replace(/alpha\(opacity=(.*)\)/gi, &#39;&#39;) +result;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//IE里filter需要触发hasLayout属性<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;styleObject.zoom = 1; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return value;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get: function(el, css, presudo) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var result = &#39;&#39;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (result = (Style.get(el, &#39;filter&#39;) || &#39;&#39;).match(/opacity=(.*)/i)) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (result &amp;&amp; result[1]) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return parseInt(result[1], 10)/100;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />}</div>code &amp; demo :<br /><a href="https://github.com/ranklau/marmot/tree/master/labs/style" title="https://github.com/ranklau/marmot/tree/master/labs/style" target="_blank">https://github.com/ranklau/marmot/tree/master/labs/style</a><br /><br />示例2, 用typedef来进行dom事件兼容<br />先看看结果代码:<div class="code" id="codeFragment2">//typedef, 是C里用了重定义类型的方法, 常见于定义struct.<br />//思路借鉴到脚本里,含义是将某个类型经过转化,可以定义成另一类型,如:<br />//用typedef去做了个hook使mouseenter和mouseleave都能得以兼容所有浏览器<br />_typedef(&#39;mouseover&#39;, &#39;mouseenter&#39;, function(e, handler) {<br />&nbsp;var el = this, target = e.relatedTarget || e.fromElement || null;<br />&nbsp;if (!target || target == el || dom.contains(el, target)) { return null; }<br />&nbsp;return handler.call(el, e);<br />});</div>code &amp; demo:<br /><a href="https://github.com/ranklau/marmot/blob/master/labs/typedef" title="https://github.com/ranklau/marmot/blob/master/labs/typedef" target="_blank">https://github.com/ranklau/marmot/blob/master/labs/typedef</a><br /><br />为了兼容而兼容吗?<br />代码如果仅仅为了兼容而兼容那太悲催了.<br />如果我们把这个思路扩展开,则是针对规范接口编程的一种解耦方式.<br />用这种变换的思路可以做很多事.<br />例如qwrap里的jss.示例3, 用jss来进行dom与js解耦<div class="code" id="codeFragment3">Jss.addRules({<br />&nbsp;&quot;.d&quot;: {dataType:&#39;d&#39;, minValue:&#39;2008-01-01&#39;},<br />&nbsp;&quot;.n&quot;: {dataType:&#39;n&#39;, minValue:0},<br />&nbsp;&quot;.email&quot;: {dataType:&#39;email&#39;},<br />&nbsp;&#39;#fromDate&#39;: {minValue:&#39;2011-11-12&#39;}<br />});<br />alert(W(&#39;#fromDate&#39;).jss(&#39;minValue&#39;));</div><br />框架层次的代码<br />这个示例没有代码.<br />通过中间层去作变换,添加一些功能.从设计模式的理解是针对这样的模式有一个例子: decorator.我们所说的函数变换,在常规语言里的大多数场景里都是decorator. --- 动态地给一个对象/函数添加一些额外的职责.<br />js的函数用起来爽的一个很重要原因是不用去声明接口,不用再添加一个额外的Object/Class去处理中间层,只用一个函数+closure的方式轻松实现.<br />我们可以试想, 在多个不同的ui类里,你得写多少一样的代码?<br />写show, hide,还得支持自定义事件.<br />构造函数还要加if分支第一个是HTMLElement,需要调用render,是json则create.<br />在需要链式调用的地方,你得需要写多少个return this?<br />所以需要中间层加变换，则简单得多了，这里就不写这部分代码了，有兴趣的同学自己看qw。<br />这一部分我们也可以理解为decorate<br /><br />如果有decorate,你将不用写这些一样的代码.同时还可以约束大家的代码结构与接口.<br />这种变换不是继承关系,而是组合关系.能使你的代码更易于维护. 结构上更清晰.<br />总之,程序中有合理的规则,接口约束,是通用处理与变换的基础.<br /><br />P.S,今天有点晕,语法可能有点不通顺,以后有空再改改,凑合着看吧.<br /><br />seealso:<br />降低HTML结构与脚本之间的强耦合 <a href="http://www.never-online.net/blog/article.asp?id=256" title="http://www.never-online.net/blog/article.asp?id=256" target="_blank">http://www.never-online.net/blog/article.asp?id=256</a>]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=321]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[webrebuild 2011 年会 session]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=320]]></link> 
      <category><![CDATA[开发日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Wed, 16 Nov 2011 13:43:36 +0800</pubDate> 
      <description><![CDATA[slideshare地址： <a href="http://www.slideshare.net/ranklau/mvc-10150624" title="http://www.slideshare.net/ranklau/mvc-10150624" target="_blank">http://www.slideshare.net/ranklau/mvc-10150624</a><br /><br />一些八卦<br /><br />之前答应了greengnn去讲，我心想，现在写码时间也比较少，而且现在写的东西原来也讲过。<br />而我又不愿意讲过的东西再讲一次，或来一次炒旧饭。<br />再也是怕自己的水平达不到，不好意思出去讲。迟迟没有写ppt。<br />后来让他帮我选题吧，选了个MVC的topic。刚好最近一直在思考和经历过一些这方面的事情，所以也就定这个方向的topic了。<br />ppt讲得不久，关键字在ppt中没有强调，如果不想翻ppt的话，我觉得自己讲的想法主要有三个方面：<br /><br />1) 之前写Controller一些经历以及为什么会让前端写Controller。<br />2) MVC前端写Controller现在是否合适，什么时候合适？<br />3) Controller看起来像程序员，但不能忘本。前端开发工程师从字面上拆开来看，前端是很重要的。需要用可用性，用户体验，速度来衡量你是否是一个好的前端开发工程师。<br /><br />后来Twinsen Liang给我们来看临时通知，让大伙坐上去。现场问答=。=<br />在rebuild年会前一天还和月影ivershuo聊了一晚上，吃了个梭边鱼。聊产品呀聊技术，蛮开心的。<br />我想最近这半年变数比较大，感悟也很多，有时间再写偏博客来说说。]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=320]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[呼伦贝尔游的几张照片]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=319]]></link> 
      <category><![CDATA[生活日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Mon, 08 Aug 2011 12:05:22 +0800</pubDate> 
      <description><![CDATA[<div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6027/6016693788_149811e489_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6027/6016693788_149811e489_z.jpg" alt="http://farm7.static.flickr.com/6027/6016693788_149811e489_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6144/6016136621_80fa51b162_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6144/6016136621_80fa51b162_z.jpg" alt="http://farm7.static.flickr.com/6144/6016136621_80fa51b162_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6141/6016137457_48d4f44b93_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6141/6016137457_48d4f44b93_z.jpg" alt="http://farm7.static.flickr.com/6141/6016137457_48d4f44b93_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6016/6016143997_2c676523e3_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6016/6016143997_2c676523e3_z.jpg" alt="http://farm7.static.flickr.com/6016/6016143997_2c676523e3_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6136/6016159861_4affbf7408_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6136/6016159861_4affbf7408_z.jpg" alt="http://farm7.static.flickr.com/6136/6016159861_4affbf7408_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6004/6016254241_fb69d4bb7b_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6004/6016254241_fb69d4bb7b_z.jpg" alt="http://farm7.static.flickr.com/6004/6016254241_fb69d4bb7b_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6142/6016781576_e0fa3441d3_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6142/6016781576_e0fa3441d3_z.jpg" alt="http://farm7.static.flickr.com/6142/6016781576_e0fa3441d3_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6022/6016780322_75bc0477ec_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6022/6016780322_75bc0477ec_z.jpg" alt="http://farm7.static.flickr.com/6022/6016780322_75bc0477ec_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6016/6016157935_779e9d9f34_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6016/6016157935_779e9d9f34_z.jpg" alt="http://farm7.static.flickr.com/6016/6016157935_779e9d9f34_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6029/6016710608_b83334bbb8_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6029/6016710608_b83334bbb8_z.jpg" alt="http://farm7.static.flickr.com/6029/6016710608_b83334bbb8_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6008/6016706512_d246f9434f_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6008/6016706512_d246f9434f_z.jpg" alt="http://farm7.static.flickr.com/6008/6016706512_d246f9434f_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6029/6016700104_33e9bf8f07_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6029/6016700104_33e9bf8f07_z.jpg" alt="http://farm7.static.flickr.com/6029/6016700104_33e9bf8f07_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6135/6016701922_f91ec3c378_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6135/6016701922_f91ec3c378_z.jpg" alt="http://farm7.static.flickr.com/6135/6016701922_f91ec3c378_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6124/6016151539_773f5ebc2d_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6124/6016151539_773f5ebc2d_z.jpg" alt="http://farm7.static.flickr.com/6124/6016151539_773f5ebc2d_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6013/6016703430_e6c2cbcbb7_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6013/6016703430_e6c2cbcbb7_z.jpg" alt="http://farm7.static.flickr.com/6013/6016703430_e6c2cbcbb7_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6029/6016698086_0251a6a9db_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6029/6016698086_0251a6a9db_z.jpg" alt="http://farm7.static.flickr.com/6029/6016698086_0251a6a9db_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6013/6016696994_d86533a1b8_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6013/6016696994_d86533a1b8_z.jpg" alt="http://farm7.static.flickr.com/6013/6016696994_d86533a1b8_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6128/6016143377_2f6331d3ba_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6128/6016143377_2f6331d3ba_z.jpg" alt="http://farm7.static.flickr.com/6128/6016143377_2f6331d3ba_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6146/6016141623_eb1dc9f418_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6146/6016141623_eb1dc9f418_z.jpg" alt="http://farm7.static.flickr.com/6146/6016141623_eb1dc9f418_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6022/6016142819_39d2347f5f_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6022/6016142819_39d2347f5f_z.jpg" alt="http://farm7.static.flickr.com/6022/6016142819_39d2347f5f_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6029/6016145973_984cbc3eea_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6029/6016145973_984cbc3eea_z.jpg" alt="http://farm7.static.flickr.com/6029/6016145973_984cbc3eea_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6121/6016138203_38eeeaefe6_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6121/6016138203_38eeeaefe6_z.jpg" alt="http://farm7.static.flickr.com/6121/6016138203_38eeeaefe6_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6130/6016139009_c68fa86fed_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6130/6016139009_c68fa86fed_z.jpg" alt="http://farm7.static.flickr.com/6130/6016139009_c68fa86fed_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6140/6016692290_c27e600c75_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6140/6016692290_c27e600c75_z.jpg" alt="http://farm7.static.flickr.com/6140/6016692290_c27e600c75_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6003/6016687668_86db875efe_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6003/6016687668_86db875efe_z.jpg" alt="http://farm7.static.flickr.com/6003/6016687668_86db875efe_z.jpg" class="imgBorder"/></a></div><br /><div style="width: 100%;overflow-x : auto;"><a href="http://farm7.static.flickr.com/6003/6016135033_211a847822_z.jpg" target="_blank" rel="lightbox"><img src="http://farm7.static.flickr.com/6003/6016135033_211a847822_z.jpg" alt="http://farm7.static.flickr.com/6003/6016135033_211a847822_z.jpg" class="imgBorder"/></a></div>]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=319]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[marmot d2 session]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=318]]></link> 
      <category><![CDATA[开发日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Tue, 12 Jul 2011 19:54:01 +0800</pubDate> 
      <description><![CDATA[去的时候几经波折, 17:10分的飞机,我差点勿机, 正当我急忙进候机厅的时候,发现飞机晚点, 最后可耻的晚了三个小时, 果然东航比较坑爹.<br />回来是是13:50飞机, 中午和dh吃饭时, winter和裕波据然还没起=.=, 最后等到齐时,我已经快走了. 等哪天我再去上海宰winter他们一顿吧.<br /><br /><div style="width: 100%;overflow-x : auto;"><a href="http://www.marmotu.com/resource/captura-1.png" target="_blank" rel="lightbox"><img src="http://www.marmotu.com/resource/captura-1.png" alt="http://www.marmotu.com/resource/captura-1.png" class="imgBorder"/></a></div><br /><br />在d2的session keynote, 用户行为在前端来说是第一次, 这次是联合演讲的方式, taobao的两位同学先讲taobao显微镜.<br />taobao同学对热力图做得比较细,也做了三维分析样本.<br />随后,我主要讲了一下做marmot的原理,设计框架,和部分实现细节.<br /><br />我之前准备放一些内部使用的video, 但在讲的前一天晚上,最后放弃了只是给一些截图. <br />让大家重点不要放在技术细节上.<br /><br />再次感概一点, 千万不要认为一个很好的产品里一定要用多牛的技术, 其实用最朴实的技术做出有价值的产品就会让人惊艳.<br />而marmot里也许没有一些高新科技,唯一值得说的也就是canvas了, 但是我们能把一些朴实的技术串联起来, 打造了属于自己的一条珍珠项链.<br /><br /><a href="http://www.slideshare.net/ranklau/marmot-d2-session" title="http://www.slideshare.net/ranklau/marmot-d2-session" target="_blank">http://www.slideshare.net/ranklau/marmot-d2-session</a><br /><br />本次的d2 accessibility 貌似比较热, 也反响比较好,本次的布道大于学习. 与其追求新技术,不如脚踏实地把体验做好.<br />从前端开发工程师这个职业来说, 有多少人真正把&quot;前端&quot;这两个字做好了?<br /><br />最后感谢下秦歌,及d2主办方还有澄静 给了我打酱油的机会.]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=318]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[技术人员说点产品]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=317]]></link> 
      <category><![CDATA[生活日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Sun, 29 May 2011 00:06:57 +0800</pubDate> 
      <description><![CDATA[一直做技术,心血来潮,说点自己对产品的一些看法.<br /><br />现在lbs比较火, 然后到o2o,再到solomo.<br />产品的趋势越来越 垂直化,社区化,标准化,个性化.<br /><br /><b>关于个性化</b><br />那如何能与上面的终端展现结合呢. 先想一个我的个人需求,一直以来,点评网虽然我是有目的是搜索我想要去的餐馆,但是不知道我想吃什么,于是我一般会在手机端用得较多,然后gps定位,然后做筛选,看评级和评论.很麻烦.<br />试想:<br />dianping我个人觉得它应该做下checkin和checkout. checkin与checkout是个粘住用户的手段,不是目的,最终的目的是挖掘出用户的行为,为个性化服务.想想,我每次checkin的都是川菜馆子,喜欢吃鱼,那么点评可以完全为我定制化一种符合我口味的推荐.那将是非常有竞争力的产品呀.<br />如果把这块挖掘深了, 团购产品的决策人员应该不会那么费劲的去想今天应该为用户推荐什么了.直接可以通过checkin看看数据上架团购馆子.<br /><br />曾经从某处看到个酒店, 如果你第一次去这个酒店,他会认真记录的放东西的使用习惯. 你下次再chekin这家酒店的时候,有可能都是上次帮你拎行李的人,你的遥控器放的位置与上次一样<br />喜欢吃什么东西,喝什么酒都与你的口味类似. 非常之人性化.<br /><br />个性化是深度挖掘用户需求,通过机器或人肉的方式来进行系统的个性推荐. 从数据挖掘后端到产品前端都是可以做很多事的:)<br /><br /><b>关于社会(social)化</b><br />社会化是信用体制的突破口, 现在点评的信用都是扁平化. 普通情况下是可以适用的.比如像是吃饭这种事情, 可以通过评论可以汇总出现在这家店点得最多的人是什么. 但也会怀疑五毛党的存在,会使你的决策考虑得更多.<br />再举taobao的例子,taobao我买过多次衣服.上次农历年前我在taobao上买了一件衣服.国外代购,都是给的五星,评论上没有太多可以看的内容.但是一买回来,小了.<br />还有就是我打算去拍婚纱照,现在网上就没有一个我能信得过的商家,但线下找的话,成本一般比较高,毕竟单个商家的线下推广成本高,羊毛出在羊身上.所以线下价格都比较贵.<br />还有一些例子就不再说了...<br />如果sns化之后,可以做的事情是,信用社会关系化.例如点评网,看点评出现的应该是我的朋友点评优先权重,避免五毛党捣乱.这对我的决策也影响颇深.<br />从拍婚纱照来说,我的朋友去某工作室拍的话,我肯定也会去咨询这家工作室,也很大可能就一起拍了. 或者人多一些就形成自然的用户驱动的团购.<br /><br />taobao c2c这一市场与b2c的评台来对比,最大软肋就是信用,现在taobao做sns化之后应该会用sns在信用这块做不少工作.<br />另外是sns化之后对于个性化的推荐也是有帮助的. 如果sns+标签,我的所关注的人群里也有和我一样的标签,喜欢一样类型(例如户外)的衣服. 他哪天购买了lowa的鞋,那么我极有可能也会去看看相关商品,从而使我购买欲望增强.<br /><br />再试想, 目前百度的搜索行为是通过query词来看你的用户行为,从而出现广告,facebook的广告则是通过关系的精准度来出现广告,从两者比较来看,facebook的广告效果好于百度效果.<br />再从目前搜索结果来看,我们看到的结果通常是后台通过反向链接的形式出现ranking结果.这样想一下:<br /><br />我与小明是朋友,我们同时搜索一个关系词: 婚纱摄影<br />我点击跳转到了一个工作室<br />小明搜索时,如果我点击的那个工作室内容排名很靠前,或者在结果里显示那条工作室结果是你的朋友(包括我)多少次点击进入的话....<br /><br />那搜索技术在排名算法上就更和谐了.<br /><br />毫无疑问.以后sns+*是一个方向.<br /><br /><b>关于标准化</b><br />最典型的莫过于zol.com的数码标准库了,在进行了seo之后往往搜索引擎第一条都是zol的内容<br />例如: <a href="http://www.baidu.com/s?wd=canon+40d" title="http://www.baidu.com/s?wd=canon+40d" target="_blank">http://www.baidu.com/s?wd=canon+40d</a><br />我现在买数码产品比较性价比往往都是通过zol去比对的.相信不少人和我一样吧.<br />标准化的目的是进行比较,而不是消费.所以zol的在线购买并不多.购买这一环节往往是在b2c里发生.<br />所以标准化对导购影响是比较大的.<br /><br /><b>关于垂直化</b><br />或许垂直化这是大家的切入点, 每个企业或网站的战略方向不一样,做广做精都有.<br />但不可否认的是,近年来越来越多的垂直化内容受到很多人的青睐.<br /><br />买数码到京东和绿森<br />买书到dangdang,和chinapub<br />家居都红孩子<br />搜机票到qunar<br />衣服到vancl<br />母婴还有babytree<br />吃饭地方找点评<br />....<br />就拿sns来说,现在装扮都有垂直类的sns美丽说.<br /><br />现在形形色色的网站都有了,每个网站都有自身的相对竞争优势.<br />以后还会出现更多只专注于某一块业务的网站.<br /><br /><b>总结</b><br />其实以上各方面都是可以结合在一起的, 所以才有了solomo这么个说法.就是个性化+社区化+移动化的一个体现.<br />但如何结合出一些既有很好的用户体验的用户产品和能赚钱的商业产品.每家公司都不太一样.重点也不一样.<br />还有很多垂直领域,或者说我想要的那种产品都还没有出来,呵呵.说不准哪天俺也做个demo出来玩下.]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=317]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[用户行为系统 如何记录行为数据]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=315]]></link> 
      <category><![CDATA[开发日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Thu, 07 Apr 2011 23:45:43 +0800</pubDate> 
      <description><![CDATA[最近准备把内部我主持负责的前端的用户行为系统代码开源了, 内部名称为marmot.<br />开发人员: seven, cyhello, rank<br />简短的说明一下marmot的一些log基本思路.<br /><br />讲解下大略的东西.<br />1. 解决不同分辩率的策略.<br />2. 解决粒度过细的问题.<br />3. 还原路径问题.<br />4. 何时发回数据及数据量的问题<br /><br />一,分辩率策略.<br />默认原点以p(0,0)开始计算,如果是定宽页面,p(0,0)坐标在不同辩率下得到的坐标是不同的.如何解决这一问题.<br />普遍情况下会采取截面坐标. 分析目前页面几种类型<br />a)align left 截面坐标从p(0,0)<br />b)align middle 截面坐标从p(document.documentElement.scrollWidth/2|0,0)<br />c)百分比的宽其实也是可以定位的,原理也是引入相对坐标系, 但也有一些劣势,就暂时不谈了.<br /><br />二,粒度切分<br />默认粒度为pixel(1,1),即1像素为单位. 优点,数据齐; 缺点,数据大.<br />大多数时候是不需要pixel(1,1)的.<br />所以解决这一问题很简单<br />页面做grid, pixel(n,n).<br />数量为: Math.floor(document.documentElement.scrollWidth/n)<br /><br />三,还原路径<br />可以序列化DOM path成selector. <br />以previousSibling + ancestor为基础不断向上递归出presudo selector(伪selector).<br /><br />四,何时发回及数据量<br />beforeunload异步发回. <br />数据量不会太大, HTTP 里 get我们所知, IE6 2k数据(已知). IE7+5K左右(记得之前我测过, 印象中是这个数据,对于此,我不纠结它的多大数据量), 非IE都有&gt;=2K.<br />肯定有人问题发回的比例是多少, 据dron同学统计过,约80%左右.<br />虽说不是绝对发回来, 但足够你用. <br />采样率5k~1w左右pv操作, 数据最大2k*1w约 20~30M log, 不算大.<br /><br />代码不贴了, 等开源再说.]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=315]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[*nix下关于配置的一些笔记]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=312]]></link> 
      <category><![CDATA[开发日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Thu, 07 Apr 2011 23:32:14 +0800</pubDate> 
      <description><![CDATA[最近一直在做一些服务器配置方面的东东, 记录下来, 备以后用.<br /><br /><b>环境变量设置 (Mac OS X 10.6 Snow Leopard 中设置PATH环境变量) </b><ul class="ubb-list" ><li>sudo vim /etc/paths将路径添加到里面去， 一行一个路径</li><li>或者vim vim /etc/bashrc在里面和unix一样用export命令添加</li></ul><b>安装python MYSQLdb, 环境mac os x 10.6, linux其它环境类似</b><ul class="ubb-list" ><li> 安装python MYSQLdb, 环境mac os x 10.6, linux其它环境类似</li><li> 0. 确保 mysql 的 configure 参数里面有 --enable-thread-safe-client</li><li> 1. <a href="http://pypi.python.org/pypi/setuptools" title="http://pypi.python.org/pypi/setuptools" target="_blank">下载 setuptools</a>，确保 $PATH 里面有 &quot;python2.6&quot;，运行 sh setuptools-0.6c9-py2.6.egg 完成安装</li><li> 2. <a href="http://sourceforge.net/projects/mysql-python/files/" title="http://sourceforge.net/projects/mysql-python/files/" target="_blank">下载 MySQLdb</a>  选择其中的 tar.gz 版本 </li><li> 3. 确保 $PATH 里面有 mysql_config，解开 MySQLdb 的 tar.gz，进去运行 python setup.py build; python setup.py install</li><li> 4. 确保 libmysqlclient_r.so.15 可以被直接找到 (方法是 sudo vim /etc/bashrc; 添加export DYLD_LIBRARY_PATH=/usr/local/mysql/lib/)</li><li> 5. 测试运行 python -c &quot;import MySQLdb as mysql&quot;，如无错误trackback则表示安装成功.</li></ul><b>vim的相关设置</b><br />session保存<ul class="ubb-list" ><li> vim ~/.vimrc</li><li> 加入</li>au VimLeave * mksession! ~/.vim/session/%:t.session<br />au VimLeave * wviminfo! ~/.vim/session/%:t.viminfo<br /><li> 因为需要在vim里source session路径,所以需要加个批处理.写个bash.命名为vim.sh保存至~路径下.</li>#!/bin/sh<br />#dir=`pwd`<br />if [ -r ~/.vim/session/$1.session ]; then<br />        /usr/bin/vim &quot;+source ~/.vim/session/$1.session&quot; &quot;+rviminfo ~/.vim/session/$1.viminfo&quot;<br />else<br />        /usr/bin/vim $1<br />fi<br /><li> vim /etc/bashrc, 将刚才写的批处理bash设置别名: alias vim=&quot;sh ~/vim.sh&quot;</li><li> 搞定.</li></ul><b>apache动态编译so包</b><br />当apache静态编译完之后,有可能有些模块在之前没有编译进去,这时候可以用apache自带的服务器<a href="http://www.phpchina.com/manual/apache/programs/apxs.html" title="http://www.phpchina.com/manual/apache/programs/apxs.html" target="_blank">apxs编译</a>和安装扩展模块的工具来安装<ul class="ubb-list" ><li> httpd -l 查看目前静态编译完毕后是否有mod_so.c</li><li> httpd -v 查看目前apache的版本</li><li> 去官方下载一个与当前服务器版本相同的安装包, 查找你想要的模块,例如gzip压缩的模块: find . -name &#39;mod_deflate.c&#39;</li><li> 用<a href="http://www.phpchina.com/manual/apache/programs/apxs.html" title="http://www.phpchina.com/manual/apache/programs/apxs.html" target="_blank">apxs编译</a>:</li>/home/xxx/httpd/bin/apxs -i -c /home/xxx/httpd-2.2.17/modules/filters/mod_deflate.c<br /><li> 编译完将mod_deflate.so 拷贝到apache的modules目录</li><li> 加入配置到apache conf里:</li>&lt;ifmodule mod_deflate.c&gt;<br />DeflateCompressionLevel 9<br />AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-httpd-php<br />AddOutputFilter DEFLATE js css<br />&lt;/ifmodule&gt;<br /><li> 重启apache.</li></ul><b>服务器日志切分</b><br />目前用cronolog的比较多, 安装比较简单.<ul class="ubb-list" ><li><a href="http://cronolog.org/download/index.html" title="http://cronolog.org/download/index.html" target="_blank">下载最新版cronolog</a>, wget下来: wget <a href="http://cronolog.org/download/cronolog-1.6.2.tar.gz" title="http://cronolog.org/download/cronolog-1.6.2.tar.gz" target="_blank">http://cronolog.org/download/cronolog-1.6.2.tar.gz</a></li><li>root用户安装: ./configure &amp;&amp; make &amp;&amp; install</li><li>查看cronolog路径, which cronolog, 默认应该在/usr/local/sbin/cronolog</li><li>配置CustomLog &quot;|/usr/local/sbin/cronolog /www/logs/access_log.%Y%m%d.log&quot; combined</li></ul><b>php,apache设置</b><ul class="ubb-list" ><li>因为我用keepalive机率不多,所以一般在apache里关掉, 而且会设定超时的阀值.</li><li>php里内存默认使用限制在8M, 最好调大一些,因为在大数据量查询及交互情况下8M肯定是有问题的.会提示</li>&quot;PHP Fatal error:  Allowed memory size of 8388608 bytes exhausted&quot;<br />php里可以调函数, ini_set(&quot;memory_limit&quot;,&quot;16M&quot;); <br />或者在php.ini里设置 memory_limit = 16M<br /><li>apache默认是把静态资源cache模式开启的, 而且是用Etag, Etag的使用还是有inode, 如果多机部署的话,inode都会不一样,前端搭建负载均衡的话,cache命中策略会大大降低.</li>所以,尽量用expire模块的cache+last_modifed.</ul><b>secureCRT ssh登录终端中文显示乱码问题</b><br />不是secureCRT的字符编码范围不对,就是服务器不支持中文gbk字符集. 所以.<ul class="ubb-list" ><li>终端机器中字符编码更改. vim /etc/sysconfig/i18n, 改为:</li>LANG=&quot;zh_CN.GB2312&quot;<br />LANGUAGE=&quot;zh_CN.GB2312:zh_CN.GB2312:zh_CN&quot;<br />SUPPORTED=&quot;zh_CN.GB2312:zh_CN:zh:en_US.UTF-8:en_US:en&quot;<br />SYSFONT=&quot;latarcyrheb-sun16&quot;<br /><li>secureCRT在session option下的Apperance中的Character字符编码集选,UTF-8或OEM.</li></ul>]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=312]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[关于前端开发那些事（五）激励体制]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=314]]></link> 
      <category><![CDATA[开发日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Thu, 24 Mar 2011 12:47:05 +0800</pubDate> 
      <description><![CDATA[<b>冰山模型</b><br />基本每个公司都会给大家说每个人的冰山模型. 对于一个中国目前广大基层代码编写者及基层管理者来说.<br />所谓的这个模型灌输给大家的目的: <br />大家不要想公司加上去,因为目前已经够温饱了. 再就是让大家更多的去做指导工作. 从成就感入手去解决你目前团队的问题.<br /><br />可是不管是哪位老师的培训都似乎没有提到<br />1. 这个调查是在国外还是国内?<br />2. 这个公司的员工在该公司的工作时间有多长了?<br />3. 这个公司所从事的是什么工作类型?<br />...<br />等等, 这里的每一个变量将会影响到全局的结果.<br />是故意呢?还是确实没有这类似的调查.也或许是我钻牛角尖?<br /><br />我要阐述我的一个观点, 马克思的政治经济学里有说&quot;所有社会问题, 都是经济问题.&quot; 所以, 从实际利益出发考虑问题会更合时宜.<br />回到刚才的冰山问题. 我们应当把人分成维度来考虑. <br /><br />在天朝,大多数都会考虑买房的问题. <br />这个问题的本质就是需要更多的工资来实现, 虽然遥远, 但我们得承受目前的工资水平要在一线城市买房的话,还贷使得你很大程度上就得呆在一个公司不走了.<br />即使. 对方公司给你更多的收入. <br />你的机会成本仍然很大, 你的人际关系.你现在已经习惯的工作方式.你的稳定性...等等. <br />这对于工作两年之后的人来说, 我认为普遍存在这一情况, 另外, 有子女的情况要求会更迫切一些.<br /><br />对于毕业学生呢. 通过调查, 更重要的是成长环境. <br />好的导师.好的成长环境, 给他们更多机会. <br />提到导师的话, 请回到第一个用户维度.<br /><br />对于成就感. 每个人有不一样的价值观, 人生观. 所以各人的成就感有所不同.<br />对于刚进公司的人呢? 上线一个项目就已经非常高兴了, 因为他的一个上线是给xxx万人用. 这种成就感使得大家更有动力去做更多的事. <br />而对于一个上线n次的技术人员来说呢? 也许你的程序如何高科技. 如何能够在一个技术型的公司受到认可, 这才是成就感. <br />因为对于上线来说, 这种认可已经麻木.<br />...<br /><br />我上面的陈述即是把成就感与激励相结合. <br />否则成就感极有可能就是在没有办法的情况下的自我安慰与自我麻痹.<br /><br />综上所述, 我想说的是, 沟通是领导能够深得人心的重要保证，激励是领导能够留住人心的重要措施。<br />如果说谁能够有能力, 有权力的在公司内建立一个有效的激励机制. 那必定是个神人. 吾将膜拜之. <br />虽无此人, 但公司也应为此上下而求索.<br /><br /><b>激励机制</b><br />定义:管理者依据法律法规、价值取向和文化环境等，对管理对象之行为从物质、精神等方面进行激发和鼓励以使其行为继续发展的机制。<br /><br />现在所有的公司都不可能提供一种完美的机制给你, 也不可能对于所有的人都公平对待. <br />另外一点也是因为这种价值如何衡量目前没有完全的量化标准.<br />如果谁能发明一种较完善的激励机制或者能对公司情况设计一种合理的激励机制,那也是相当的人才呀.<br /><br /><b>打怪型的激励机制</b><br />像某些公司用量化式的工具也衡量每个人的工作量, 这个工作量直接与奖金挂钩, 也会有所不公平.<br />这就像是玩网游在打怪. 如果你遇上大的怪经验值就会多, 反之则少. <br />怪物的大小直接取决于你这个部门的价值及直属上级对这个项目的判断力, 这对项目经验这样的底层管理人员提出了很高的要求.<br />优点则是公平,公开和公正. 这是所有开发人员都想看到的. <br /><br />对于公司,则是收益较大的, 劳动密集型的开发,使得公司保持了高效率的迭代.<br />这些公司之所以长期采取这样的方法,应该是价值的总剩余大于不公平因素.<br /><br /><b>技术驱动型的激励机制</b><br />一些公司采取的kpi导向,但纵观这些kpi内容,都是与业绩相关.<br />而也会配套的采取一些技术驱动型的激励, 例如.你现在做了多少项目,有多少是有技术含量的,有多少是可以值得拿出来说的.<br />如若是你每天都写业务码, 再加上你现在的流量不高, 那么很对不起, 技术影响力不够大. 在这样的技术评级体系下,你是很吃亏的.<br />反过来说, 如果你是在核心部门,或许,我说的是或许,也相对于非核心部门的同学在评级机制下会稍好一些.<br /><br />对于公司来说, 这样的机制如果有足够量化的评机系统,还是不错的,既能鼓励创新,又能保持自己公司较好的技术水平.<br />但是,要注意的是激励会改变人们的行为.<br />这里的问题在于, 1.激励会使人去研究新技术,即使是别的部门研究过. 2.即使现在用不着这样的技术,也会有人去玩. 3.评级体系的负责人不了解你的产品线.4.有可能你现在没有办法利用或研究出新的技术以用于自己的产品线.<br /><br />所以,有可能久而久之的现象则是,大家都不太想干活了. 因为干活的多少只会影响奖金.而这个奖金是效用是否能够大于升级的效用呢?<br />这个因人而异.<br /><br /><b>价值型激励机制</b><br />用最简单的模型来描述一下.<br />一个公司,两个人.一个老板,一个业务员工.<br />老板怎么样能激励员工,让员工给公司创造最大的价值?<br />这种应该是很多人都知道. 如果员工为老板带来了100万的生意, 而利润有20万的话.<br />老板愿意将一定利润的比例做为报酬, 这样员工会比较能够发挥主观能动性.<br />在我所了解的资料中, 万科属于这种类型.<br />在万科公司中, 如果你提的建议为公司节约下多少成本,或提高多少工作效率. 经过量化之后会乘以一个比例,把这部分的钱作为给提出,执行者的激励.<br />这样的好处在于, 大家都在为公司想办法节约成本,提高生产力.<br />不好之处在于,上班大家还是否热衷于真的上班?<br /><br /><b>不能当作银弹</b><br />各种激励之模型都有优有劣,但国内各稍微成熟的公司都有自己的一套办法, 但是,对于新的业务部门及创新型部门, 却是不能用成熟体系拿来衡量的.<br />薪酬激励象通货膨胀.<br />创新型及创业型的团队应该有会较好,直接的激励体系用于鼓励创新行为,可以以透明的奖金来体现.<br />而成熟的业务里则是稳中求胜,不能盲目的用激励来刺激大家,以免造成激励过剩.<br /><br /><b>领导的作用</b><br />领导做的事是管理. 管理在本质上就是几个关键字, 即是决策, 团队, 规划, 资源, 执行.<br />但是如何能够最有效率, 则各有各的权重. <br />领导其实很多时候也很难做, 上有压力,下面也有骂声,如果协调不好,上不去下不来.两面都逼着难受. 也不光是用智商就能解决的.<br />能解决好的,那是一种智慧. 让人敬佩.<br /><br />对于激励体系,要看你的上级如何看待此事, 当你的上级拿着较好的待遇时,是否能够体谅员工的辛苦呢?.<br />如果他能够关注细节,了解员工所想, 对员工来说这才是一个好的领导.<br />不写码的领导是很难理解,它的一句话下来让大伙全改, 然后他还以为大家都很有激情工作, 却不知道大家在后面相互吐不快.<br />工资高的领导是很难理解,公司的一点福利对于员工有多重要.<br /><br />不断有故事提醒我们, 有很多事, 不是屁股能决定脑袋的.]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=314]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[关于前端开发那些事儿(四) 技术的本质何在?]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=311]]></link> 
      <category><![CDATA[开发日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Thu, 24 Mar 2011 12:46:02 +0800</pubDate> 
      <description><![CDATA[<b>技术职称,kpi说起</b><br />一般技术公司都有一年一次,或者两次的技术评定. <br />不论是KPI还是技术评定, 都想从相对客观的角度去衡量一个人对公司的贡献有多大, 基本是从几个维度给出评分再乘以权值的算法.<br />肯定也有很多人会怀疑这种算法的公正性, 但即使愤青,也只能无可奈何的接受现实给你的打击.<br />这是体制. 每个公司成功都有自己的理由, 只说说自己的感受.<br />正如蔡学墉先生所言(我稍修改了一下), 评级或kpi三阶段一般是:<ul class="ubb-list" ><li> 忽略kpi和技术职称导向, 为部门所想, 全情投入.</li><li> 几乎全kpi或技术职称能力导向</li><li> 无导向, 此时已经很难回头了.</li></ul>做过开发有几年了, 环境有所变迁, 自己的想法有的时候也常变. 我也想罗嗦一下乱七八糟的事.<br /><br /><b>创业激情</b><br />刚进公司我对这套大公司的做法几乎忽略. 以全部的创业激情投入到工作中, 到年底也很幸运,部门得了总裁奖,整体部门也得到了较大的回报.<br />忆当年, 晚上11点了,部门内部还是灯火辉煌, 凌晨一两点有人还在加班也是很常见的. 这个时期可以认为是轴心时代.<div class="quote"><div class="quote-title">引用 <u></u></div><div class="quote-content">人类都有个轴心时代，人类一直靠轴心时代所提供的思考和创造力的一切生存，每一次飞跃都回顾这一时期，并被重新点燃，自那以后，就是这样，轴心时期潜力的苏醒和轴心期潜力的回归，或者说是复兴，总是提供精神的动力。——雅斯贝斯《历史的起源和目标》</div></div>我现在理想的分析过去为何那么有干劲的半夜去加班:<ul class="ubb-list" ><li> 有美好的未来. 画个饼不难, 不外乎是未来的美好. 而当时每个人都会认为只有它才能与taobao竞争,说实话,这个饼,确实挺诱人的,呵呵</li><li> 有足够的激励. 创业是个难事, 老罗同学的学校据说给的工资是比新东方还好. 当时而言前端这个职业这里给的薪水算是不错的.</li><li> 有技术的氛围. 气氛是一个很容易引起同鸣的东西, 如果大家都在卖力的干活,而你不是,那你心里会有愧疚感. 不为技术而技术, 只为产品服务.</li><li> 有很多的牛人. 其实在每个公司都有牛人, 可是出名的牛人就不一样了, 做技术的同学会朝他们的技术偶像而去, 去学习, 瞻仰, 进步.</li><li> 有很好的环境. 在创业型以及创新型的公司或团队里, 发挥团队每个人的工作效能, 最好的方法正如: 让有能力的自己去做, 其次再去教他做, 最后再管理他. 而这种方法意味着你必须是个足够开放的环境, 放权, 及足够的信任, 11点上班也无所谓, 晚上下班也任由你. 然后还给你每月几百块的旅游基金.</li><li> 信息尚不明朗. 当时大家只有心思把东西做好, 不关心其他的事情.</li></ul>呃.有点像程序员的天堂.<br /><br />世界在变, 所以天堂也不会是一直完美. 经历了创业时期的轴心时代, 都会过渡到一个彷徨的时期.<br />一些信息不公开,大家对产品的审美疲劳,内部的一些问题逐渐暴露出来. <br />很多初期时候的承诺看上去都已经太过遥远.<br />于是会有一些核心的人员开始离开这个团队, 去追求他们自己的理想...<br /><br />对于技术在此时而言, 要么是要让他们做自己喜欢的事, 要么是做改善目前状况的事.<br />前者过于孤单, 而后者力不从心.<br />需要平台, 需要能力, 需要时间.<br />这对于我来说是个有点像是质变的过程. <br />之前我会更在意于技术形态上的讨论, 现在更多的是在变现上的思考. <br />这在于我之前的日志也有提到技术变现, 这里也不多说了. <br />详细看这里<a href="http://www.never-online.net/blog/article.asp?id=307" title="http://www.never-online.net/blog/article.asp?id=307" target="_blank">http://www.never-online.net/blog/article.asp?id=307</a><br /><br /><b>技术为谁服务</b><br />技术的本质是降低成本及提高生产力.<br />这是我现在做技术上的信仰, 不唯技术是从. <br /><br />一个技术型的企业, 会有可能掉入到一个陷井, 就是我们现在不停的去挖新技术, 这对于我们个人来说都是有益的. <br />对于你出去找工作可能也有一定好处, 毕竟是技术面试, 你了解得越多当然越好. <br /><br />对于公司而言则不尽然.<br />如果公司里都是一大帮人去研究新技术了,那谁来开发项目呢? <br />何时研究新技术,何时是以效率为主的导向, 是需要项目经理及技术经理所以考虑的. 甚至KPI的制定也应该以此为基础.<br />如果不然, 则会出现非常严重的后果. <br />可能大家上班都没精神,没有方向感.<br />新人来了,看老员工都在玩技术,自己都在顶着上线和产品人员的时间天天写着业务码, 自己也会想办法从中逃出来. <br />希望自己哪天老油条了,也不必这样去写业务码.<br /><br />那问题来了, 你现在的业务如果不需要新技术, 只需要写业务码的人呢, 那怎么办, 如何保持大家对新技术的激情呢?<br />我还是那个观点,不应该为技术而技术. 如果真是那样,宁愿不去干那些事,宁愿大家把目前的主要精力体现在业务上: <br />例如如果减少代码量,编写代码生成器,自动上线,自动检查.文档生成等等.<br />本质上是 活你干或者不干, 它一直在那里. 只是没有人或者没有制度给你一种激励, 使你现在干这种提高生产力的活的机会成本 小于 你去研究新技术的成本. <br />如果这个条件成立,那一切都应该不是问题. 或是通过外部的某种激励使得你愿意把目前生产力提高上去.<br /><br />其他的也不啰嗦太多了. 相信每个人自己心中有杆秤.<br />总结一句话就是,不论何种技术,也不论你是在工程院还是研究院, 作为技术人, 在心中仍然还是要自己对变现这个词的思考, 对技术目的的思考.]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=311]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[bash shell - sed, awk文本捕获及替换]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=313]]></link> 
      <category><![CDATA[开发日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Fri, 11 Mar 2011 23:37:00 +0800</pubDate> 
      <description><![CDATA[bash shell虽然支持正则表达式, 但是正则操作却不大给力.<br />看以下示例<br /><br /><b>case需求.</b><br />stream=&#39;background-image: url (a.jpg)asdfasdfasdf ;background:url(b.jpg);background&#39;<br />需要将背景图片内容a.jpg及b.jpg后追加一个签名串.<br /><br /><b>sed替换不给力</b><br />如果用sed, 替换是不会有问题, 但是要在一句代码里进行捕获多个图, 将进行替换, 查阅了相关的sed文档, 貌似是需求处理不了.<br />代码示例<div class="code" id="codeFragment1">stream=&#39;background-image: url (a.jpg)asdfasdfasdf ;background:url(b.jpg);background&#39;<br />echo $stream | sed  &#39;s#.*url *( *\(.*\) *).*#\1#&#39;<br /><br />#输出b.jpg</div><br /><b>awk代码块</b><br />用awk的话,(g)sub又没有sed里的匹配后的&quot;后向引用&quot;(即&quot;\1&quot;). 但是可以有代码块可操作.<br />原理可利用awk里的函数match先用正则匹配url()里的内容, 再用substr将内容取出, 随之将流的位置置后.<br />循环操作.<br />代码如下:<div class="code" id="codeFragment2">stream=&#39;background-image: url (a.jpg)asdfasdfasdf ;background:url(b.jpg);background&#39;<br /><br />matches=$(echo $stream | awk &#39;BEGIN {ORS=&quot; &quot;} END {<br />&nbsp;gsub(/ */,&quot;&quot;, $0)<br />&nbsp;input=$0<br />&nbsp;while (match(input, &quot;url([^?;)]+)&quot;)) {<br />&nbsp;print substr(input, RSTART+4, RLENGTH-4)<br />&nbsp;input=substr(input, RSTART+RLENGTH)<br />&nbsp;}<br />}&#39;)<br /><br />for bg_file in `echo &quot;${matches}&quot;`; do<br />&nbsp;md5_code=&quot;test&quot;<br />&nbsp;stream=$(echo &quot;${stream}&quot; | sed &quot;s#url *( *${bg_file} *)#url(${bg_file}?v=${md5_code})#&quot;)<br />done<br /><br />echo &quot;${stream}&quot;</div><br /><b>总结</b><br />从以上的示例可以看出, awk几乎可以替代sed, 但是对于固定替换, sed使用起来更方便.<br />sed从使用理解上看, 与vi的命令操作很相似. <br />而在awk里块里几乎可以操作任意文本流.<br />另外要说明的是, 这两个命令所支持的正则都像是标准perl里的子集, 没有贪婪匹配与非贪婪匹配之分.<br />其实你应该很意外, 我为什么不用python或者php这种语言来写, 如果用字符串函数比较多的语言来写的话, 应该是非常之简单.<br />很遗憾也很高兴的, 这次有点钻牛角尖, 依然用了bash. <br />也算为学bash打下个基础.]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=313]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[bash shell里读取文件时反斜杠(backslash)原文输出]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=310]]></link> 
      <category><![CDATA[开发日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Tue, 15 Feb 2011 13:54:57 +0800</pubDate> 
      <description><![CDATA[<b>问题描述</b><br />逐行读文件一般的写法如下:<div class="code" id="codeFragment1">cat filename | while read line; do <br />echo $line; <br />done</div>看上去没有什么问题, 而且是网上的同学都让你这么读. 实则有潜在问题很难发现. <br />我们知道echo 里是默认有转义的,一个&quot;\&quot;反斜杠默认不显示,两个则显示一个,如果你的file里有如下字符<div class="quote"><div class="quote-title">引用 <u></u></div><div class="quote-content">\s\\s\s</div></div>用上述的代码则输出:<div class="quote"><div class="quote-title">引用 <u></u></div><div class="quote-content">s\ss</div></div>这着实让我头痛...<br />在Baidu和google里搜索没有合适的结果,只能自己分析了.<br /><br /><b>分析</b><br />应该不是echo的问题. echo只是输出端, 每个语言的输出都有各自的转义, 举例即是如果变量用单引号声明则是原文输出, 那么上面的line是个变量.<br />所以问题自然在要么是cat么,要么是read有问题.<br /><br /><b>测试及结论</b><br />cat file里的文件出来仍然是原文\s\\s\s<br />考虑是否是read有问题. help read出来的文档里是有参数可查的. <b>查到是参数&quot;r&quot;</b>.<div class="quote"><div class="quote-title">引用 <u></u></div><div class="quote-content">If the -r option is given, this signifies `raw&#39; input, and<br />    backslash escaping is disabled.</div></div>最后原文输出文件的内容代码如下:<div class="code" id="codeFragment2">cat filename | while read -r line; do <br />echo $line; <br />done</div>]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=310]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[bash shell杂记]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=309]]></link> 
      <category><![CDATA[开发日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Sun, 23 Jan 2011 20:54:38 +0800</pubDate> 
      <description><![CDATA[最近在给模块编写编译脚本, 大概规则是解决<ul class="ubb-list" ><li> 在css文件里 匹配@import url(&quot;/path/html5.css&quot;). 将/path里的html5.css文件内容替换当前行. 即css合并</li><li> 将js文件里的document.write(&quot;/path/dom.js&quot;). 将/path/dom.js文件替换当前行. 即js合并</li><li> 将模块打包成线上路径. 可以直接cp上线上目录. 提高上线效率,降低上线出错机率.</li><li> 将sprite的图片文件加上版本号</li><li> 将&lt;link&gt;标签里的css路径加上版本号</li><li> 将&lt;script&gt;标签里的js路径后加上版本号</li><li> css, js 代码压缩</li><li> 实现基本的检查, 例如不能将测试环境的一些代码发布上线上等等</li><li> ...</li></ul>看上去实现不算困难. 于是想直接用bash shell写. 也算巩固一下这方面的知识.<br />bash shell在*nix里很爽的机制有管道和重定向, 非常方便. 但是也有一些需要注意的点.<br /><br /><b> 管道 </b><br />管道的作用是将前一个命令的输出用作后一个命令的输入. <br />但你想写这样的代码时:<div class="code" id="codeFragment1">cnt=0<br />cat xxx.file | while read line; do<br />&nbsp;if [ ${line} == &#39;error&#39;]; then <br />&nbsp;let cnt=$cnt+1 <br />&nbsp;exit<br />&nbsp;fi<br />done</div>是不能修改cnt变量的值的. 这是因为通过管道,是在当前进程中fork出一个子进程, 因此变量上面不可修改父进程的变量. 这也合情合理. <br />那如果我想修改应该怎么办比较方便? 答案是通exit退出进程时的返回值来操作. exit能返回最后一个子进程操作的返回值.<div class="code" id="codeFragment2">cnt=0<br />cat xxx.file | while read line; do<br />&nbsp;[ ${line} == &#39;error&#39;] &amp;&amp; exit 2<br />done<br />retval=$?<br />[ $retval -eq 2 ] &amp;&amp; let cnt=$cnt+1 </div><br /><b> 文本编辑的差异 </b><br />如上面如说, 一行行的读总没问题吧? 事实并非如此. <br />之前不了解bash这些命令的原理, 于是踩了个坑. 我从svn checkout下代码后. 读取css里@import的文件发现有的能读取,有的不能读.<br />最后定位到不能读的文件都是一行. 或者是最后一行.<br />在公司群内询问之后, 有人提到可能windows的换行与*nix的是不一样. 于是将\r替换后依然不能逐行read line. <br />通过file命令查看之后, 发现奇怪的事.<div class="quote"><div class="quote-title">引用 <u></u></div><div class="quote-content">with no line terminators</div></div>如果是windows编辑出来的应该是&quot;with CRLF line terminators&quot;, 如果是no line terminators意味着没有换行, 自然是不能read line.<br />用命令&quot;od -c xxx.css&quot;确认后果然看asc码文本最后无换行.<br />这应该是windows下某些编辑器的问题. 具体就没再去查.<br />回到这个问题, 在网上搜了一下, 没有找到一些资料可参考.<br />于是我当时想到的是一个山寨办法, 给每一行末我加一个回车. 然后再保存回去, 嘿嘿. <br />也算能解决问题吧. 也咨询了一些同事, 这个目前还没有找到太好办法.<div class="code" id="codeFragment3">&nbsp;sed &#39;{<br />&nbsp;/$/ a\<br /><br />&nbsp;}&#39; ${file} &gt; ${file}.bak<br />&nbsp;mv -f ${file}.bak ${file}</div><br /><b>引号</b><br />单引号是能保持包含在单引号里的原值<br />双相号也是如此,但除了反引号&quot;`&quot;美元符及转义符&quot;\&quot;<br />但是确有所不同. 加上字符串变量加上引号会更保险<div class="code" id="codeFragment4">a=&#39;*   @@&#39;; echo $a</div>这在至少mac里会列出所有当前的文件夹下的所有文件,这是通配符&quot;*&quot;在作怪.<div class="code" id="codeFragment5">a=&#39;*   @@&#39;; echo &quot;$a&quot;</div><br /><b>log</b><br />尽可能的多输出日志, 分清info, warning, error类型,对于真正出问题时定位很有用.<br />特别是你不能在本机debug时.]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=309]]></wfw:commentRss>
    </item>
      
    <item>
      <title><![CDATA[关于前端开发那些事儿（三）技术之变现]]></title> 
      <link><![CDATA[http://www.never-online.net/blog/article.asp?id=307]]></link> 
      <category><![CDATA[开发日志]]></category> 
      <author><![CDATA[Rank <null@null.com>]]></author> 
      <pubDate>Tue, 21 Dec 2010 00:51:03 +0800</pubDate> 
      <description><![CDATA[我想现在做开发的同行有很大一部分人应该每天都在想，我们的每天的工作事项都是<br />写业务代码，项目评审，代码review，沟通业务是否符合需求。。。。<br />每天都围着技术含量不高的业务代码。。。嗯，很郁闷。<br /><br />这是个引子，业务技术不是我今天要罗嗦的主题。<br /><br />我想表达的是我们其实都想去学习，去深入的了解某项技术，更去应用，让人用，让自己有强烈的成就感。<br />可是，事与愿违，原因就是业务部门首要任务应该是完成目前业务线的工作，和产品人员沟通，然后就是直接的交易量和收入。<br /><br />对于一个做技术的开发者来说，<br />去做有技术难度事情，来挑战自己，给自己成就感；<br />与一大帮牛人在一起讨论技术；<br />保持和提高自己的数理逻辑神经；<br />这，才是归宿。<br /><br />正如google招人也正中技术人才的下怀，但千人挤独木桥，不是谁都能上的。<br />所以，我们只有在自己业务线当中不断的去满足自己的技术欲望，用工作之余去尽可能的做些有技术含量而且也可以为产品线服务的技术产品。<br /><br />从我自己在公司里去主持开发的一个非项目的技术产品来说，问题有以下几点<ul class="ubb-list" ><li> 是否有团队。如果说你是个新人，那好吧，你只有一个人。除非你之前就有影响力了，或者是运气好，能碰上合适的人让你去做这样的事。</li><li> 是否有人用。做的技术再好，如果没有人用，也是让人没有成就感，没成就感就没后续跟进的动力。</li><li> 是否有时间。每天拿出两小时来做？还是周末？这是个问题。</li><li> 是否有目标。这个目标简洁的说就是应该对公司对团队有价值的，如果仅是随意的一个项目的话，还是一个人去做会比较好，否则没办法让大家投入进去去做。这有点像是在<b>团队内技术创业</b>。</li><li> 是否有计划。这与时间紧密相关，当然也需要设定目标与规划开发周期等事宜。</li><li> 是否有名份。总不可能天天当小三，上不了台面来正式立项，项目过半可能大家就没动力了。而如何做到能正式立项这是个难点。当然，也需要有所激励。</li></ul>从我的现在的角度分开诠释下上列其中的几个点<br /><br /><b>关于团队</b><br /><br />我很幸运，有幸在之前能够带些新人，实习生；也负责了几个产品线。<br />直接上级也能放权，让我自由的去计划和控制这个组织，而新人和实习生也很出色；<br />虽然我们平时争吵，但彼此相互信任。<br />因此，对于我而言，团队是没有什么问题的，我有这个权利在我的能力范围内让开发人员参与一起开发。<br /><br />我曾在公司内的wiki里搜索很多类似的研究项目，<br />这些项目要么过一阵子就夭折了<br />要么是玩玩而已；<br /><br />而最后，仔细想想，很大程度上是没有团队在做。<br />所以，这是做一个好的技术变现的前提。<br /><br /><b>目标、成就感及回报</b><br /><br />两个选择：<ul class="ubb-list" ><li> 很累，做大家想使用的产品。</li><li> 很累，做没有人用的产品。</li></ul>当然我们有其他的选择，例如我也曾想过<br />是否也可以不累，做大家想使用的产品。<br />思来想去，还是我们用业余时间做吧。毕竟我们不是研究院，给大把时间研究能让产品间接使用的产品。<br />如果用工作时间做，则对其他的同学不是太公平。。。<br /><br />所以，我愿意选前者。<br /><br />产品有没有用在于你的目标和定位是否正确，正如前面所说，不是研究院，最多也算半个工程院。<br />所以所做的技术变现必须马上或不久就能用上，并为你现在所做的业务产生价值。<br />价值包括，降低成本或者提高工作效率等。<br />如果目标定位错误，就像是你扣衬衣的扣子，第一颗扣错，后面再扣得再好也是白费劲。<br /><br />如果定位没有问题，那么随之努力而来的就是你的推广。<br />推广是需要时机的，我们假设一出demo时就推广，可能根本没有去用，凉水就上来了。<br />毕竟是个demo而已，另外的是又担心你现在根本没人力去投入，等你真正开发完了之后可能已经人走茶凉。<br />所以我这次推广是等到有可用版本之后再做推广。<br /><br />可用版本上线之后，推进使用，然后立马产出第二个稍成熟版本；<br />接下来再修正，重构也好，增加大功能也好，这时你可以稍微慢点琢磨了。<br /><br />其实这个技术项目我两年前就想做，也做过demo，发过邮件，最后大家觉得是不错，很好，可以试试呀。<br />但最后不了了之。<br /><br />我自己总结了经验教训，这次重新出发<br /><br />目前通过这一个季度的推广与开发，终于在部门内部有反应了，<br />更让我欣喜的是其他好几个部门的人都找到我们，让我们去讲解，合作等。<br />也趁给部门技术做ppt的时候慢慢浮上水面，总算现在不是小三了，也可以开始申请域名、服务器了。<br />这也算是给我们的肯定与鼓励，是个新的起点。<br /><br />感谢团队的每一个人。<br /><br /><b>其他杂想</b><br /><br />最后，表明我的观点，在业务型的公司里用你的 技术变现 就是 创业！不知你是否也是这么想的？<br />一个项目成功健康与否除了方法论与实践外，很重要的一点就是环境。<br /><br />一个公司是否有一个环境能让技术人员产出真正对公司有利，又对工程师有利双赢的产品呢？<br />如何有一个常态的技术变现环境就好比如何有一个好的创业环境。<br /><br />怎一个难字了得？<br /><br />夜深了，刚坐飞机回来，头有点晕，可能文章思路有点乱，哪天有空再整整吧。]]></description>
      <wfw:commentRss><![CDATA[http://www.never-online.net/blog/feed.asp?q=comment&id=307]]></wfw:commentRss>
    </item>
      
  </channel>
</rss>

