<?xml version="1.0" encoding="UTF-8"?><!-- generator="WordPress/2.9.2" -->
<rss version="0.92">
<channel>
	<title>My Pool</title>
	<link>http://www.hlouis.com</link>
	<description>Help, I can&#039;t swimming......</description>
	<lastBuildDate>Tue, 04 May 2010 15:27:10 +0000</lastBuildDate>
	<docs>http://backend.userland.com/rss092</docs>
	<language>en</language>
	
	<item>
		<title>CEGUI Font module Hack</title>
		<description><![CDATA[不知道这种修改算不算得上Hack，为了能让CEGUI在亚洲系字体上能有更好的表现，需要将他的字体模块的缓冲机制（主要是Freetype字体类型）做一个比较大的修改，主要修改的内容如下：
初始化时间过长
CEGUI在初始化的时候，会便利一个字体中所有的Glyph，并在d_cp_map容器中初始化所有的FontGlyph对象。这个在英文字体下没有什么问题，因为一个字体中大约只有几百Glyph，但是在中文字体中这个值一般是65535个，所以初始化的时间过长。准备废除这个初始化的过程。
CEGUI使用一个bitmap，d_glyphPageLoaded作为一个codepoint有没有载入的标志，在这里废弃这个变量，直接使用d_cp_map容器中有没有对应的FontGlyph对象作为这个codepoint有没有载入的标志。
字体缓冲的贴图占用过多
CEGUI中的字体缓冲有一个算法，就是把字体中的Glyph分页，每个页是256个文字，一旦要渲染一个文字的时候，就把这个文字前后一共256个Glyph都渲染到一张贴图上。对于英文字体来说这样不是问题，一个字体最多渲染5到6张贴图就完事了，而且采用这种策略渲染好的贴图就不需要修改了。但是对于中文字体来说这不是一个好的策略，中文字体中文字个数繁多，而且不是采用使用频率在字体中排列的，你渲染的一个文字的前后255个文字说不定在整个过程中就不会使用得到，如果讨论在极端情况下，一个中文字体一共需要65535/256=256张贴图才可以完整的渲染完，这样我们可怜的显存里面就全部都是文字了，明显不可以接受。
计划使用一个简单的缓冲机制，就是一开始设定好一个字体可以使用多少张缓冲贴图，和每张贴图的尺寸（这里暂定512*512）。这样的策略实现起来比较简单，相对来说修改的代码量也不是很大，缺点是：

CEGUI的贴图接口中并没有锁定或修改已存在的贴图内容，需要自己实现。
原始的贴图生成之后不需要修改了，现在需要经常修改，会有一定的效率损失。

]]></description>
		<link>http://www.hlouis.com/develop/cegui-font-module-hack/</link>
			</item>
	<item>
		<title>First blog from iPad</title>
		<description><![CDATA[I&#8217;m still trying to get input method working, so this is the Twitter like post.  
]]></description>
		<link>http://www.hlouis.com/diary/firstblogfromipad/</link>
			</item>
	<item>
		<title>Google Checkout 解封纪实</title>
		<description><![CDATA[记得Nexus one刚刚出现的时候，就很激动的去使用google checkout下订单，下单之前了解清楚需要使用香港的收货地址，也找了常住香港的朋友，结果却悲剧的被google锁了账号，估计是我的信用卡的问题。于是将想到了去申述。这篇主要介绍一下如何进行申述的，帮助也有同样经历的人解决checkout被ban的问题。
其实把我的账户ban掉的原因很简单，就是我的信用卡的资料不对。不知道什么原因，google checkout内部支持的信用卡的国家地区选项里面吧中国剔除了（之前是有的，我肯定）于是我们就只能选用不正确的国家地区：香港。
我是2010-1-19日下的订单，三天之后checkout账户就被ban了，登陆checkout账户之后就提示我进行申述，于是我就准备了他要求的两种资料：

你个人的信息，可以是身份证或者是护照的扫描件，我选择的是护照的扫描件 
可以证明你信用卡归属和billing address的信息，我们的billing address本来就是不正确的，所以我扫描了我的招行信用卡的账单和我的信用卡的正面（卡号的前9位遮住） 
其他信息 

这个其他信息非常重要，我写了一篇很热情洋溢的信，由于我的英文写作很差，所以破费周折，原文如下：
&#160; I&#8217;m this credit card&#8217;s holder and I have left the correct card information. But the billing address I left was not match my bank billing address. Because there is no option &#34;China&#34; in the combobox when I was filling the billing adress form so I left [...]]]></description>
		<link>http://www.hlouis.com/diary/google-checkout-reactive/</link>
			</item>
	<item>
		<title>Domain Change</title>
		<description><![CDATA[因为一些众所周知的原因，我决定要放弃我的.cn的域名了，所以我的域名正式更改：
www.mypool.cn ======&#62;&#62;&#62;&#62;  www.hlouis.com
如果有人订阅过我的blog，请将订阅地址更新为：
http://www.hlouis.com/feed/
目前我的cn域名会持续到今年8月份到期，（当然，也可能在中途的任意时刻被停止解析）这段时间内这两个域名会同时指向我现在的网站，所以理论上会有很长的一段过渡时期。。。。。
]]></description>
		<link>http://www.hlouis.com/diary/domainchange/</link>
			</item>
	<item>
		<title>Lua can&#8217;t do math?</title>
		<description><![CDATA[今天把项目中所有使用的脚本从python替换到lua，一切看起来很美，不过最后测试的时候发现一个非常诡异的问题，具体lua语句如下：
print("simple test: ")
print((10000 + 123456789) - 123456789)
程序打印出来的值竟然是10003，顿时被雷到了。虽然我知道lua用的是double作为基础的lua_number，但是人家已经很耐心的教育我们double是双精度类型，不会出现什么四舍五入的问题。于是打开linux上的终端运行lua进行同样的计算，这次得到的是正确的结果：10000。
想想也知道lua不会有这种低级的错误的，要不还不立刻被人骂死，于是开始找自己的问题，首先怀疑是我们的lua嵌入包裹代码的问题，仔细review了一遍代码，觉得不会影响到这么底层的问题。接着开始做实验，发现在服务器上的同样lua代码，运行的结果是正确的。经过无尽的折腾，最后发现了这么一个事实：
在directX的sdk文档里面，D3DCREATE这个条目里面有这么一条：
D3DCREATE_FPU_PRESERVE Set the precision for Direct3D floating-point calculations to the precision used by the calling thread. If you do not specify this flag, Direct3D defaults to single-precision round-to-nearest mode for two reasons:
- Double-precision mode will reduce Direct3D performance.
- Portions of Direct3D assume floating-point unit exceptions are masked; unmasking these [...]]]></description>
		<link>http://www.hlouis.com/develop/lua-cant-do-math/</link>
			</item>
	<item>
		<title>Get rid of memory bugs</title>
		<description><![CDATA[大型的C/C++程序做到最后，bug高发的时期过去之后，一般来说会出现的问题都是很妖的。最最常见的现象就是一下几种：

调用栈全部混乱，一堆问号出现在这里，你明明知道自己编译的时候有放入符号，现在却什么信息都看不到 
莫名其妙的调用了一个代码里面没有调用的函数 
重复的free或者delete某块内存，然后崩溃 
部分静态或者全局的数据混乱了，代码里面除了初始化就没啥地方写过他们了 
莫名的某个对象的数据全部混乱了 

 
其实有经验的程序员看到我上面这堆牢骚就知道，归根结底，这些问题都是一个原因：内存混乱。可以直接操作内存是C/C++的效率之源也是一切的罪恶之源。没有个两三年的编程经验，很难深刻的理解内存、指针和引用这些看起来没啥深奥的问题。关于可能出现的内存混乱我大概的归纳一下：

使用没有初始化的内存 
内存越界 
内存泄漏

为了理解如何处理这些情况，我们先稍微总结一下程序的内存的使用会出现在什么地方：

静态，全局内存：静态和全局对象会在main函数之前由libc进行初始化和分配，他们因该会出现在运行的数据段上，一般来说是数据段的开头部分。问题2， 4和5可能由这种内存的混乱引起。 
栈内存：基本上可以认为是局部变量初始化的内存了，在程序入栈的时候分配，出栈的时候丢弃。这种内存混乱可能会引起问题1, 2, 4, 5 
堆内存：由malloc、new分配，由free、delete回收的内存。这种内存混乱的话，会引起2、3、4、5 

基本上想要彻底在机制上解决内存问题，肯定是没有希望的，因为如果这是可行的，那么早就有nb的人做出来，并放到标准里面了。于是他们做出了java。。。。。所以我们现在追求的就是如何能够快速的追踪到问题的源头。
不像是其他的逻辑bug，内存混乱引起的问题，现象是千奇百怪的，而且发生问题的源头往往和现象不在同一个调用栈里面，或者是整个调用栈全部乱掉，让你无从可查。所以必须要使用一些其他手段来帮助我们。根据不同的内存使用种类，我说一下自己的思路，和目前已经有的做法：

堆内存：为什么先从堆开始说起，因为堆上的内存分配和删除是完全控制在我们自己手里面的，说实话，这块东西早就有很多的工具和代码进行跟踪保护和分配了。而且相关的原理基本相通。 

最完整的办法解决这个问题是建立自己的内存管理体系，使用内存池，托管系统的malloc、free或者是new、delete。这样不仅仅可以在犯错的时候我们有机会去监测或者记录。还可以通过内存池来增加系统的效率。 
如果暂时没有成体系的内存管理系统，也可以使用第三方工具，比如非侵入式的valgrin或者是编译到代码里面的efence。这些工具都可以很好的帮你监控报告这些内存的混乱。 
对于内存溢出这个问题，不论是自己的内存管理体系还是第三方的监测工具，基本上都是一个原理。在分配内存的时候多申请一定的字节，比如20个bytes，并将他们初始化为一些特殊的字节。然后去检查这块内存有没有变化。如果有变化就是出现了溢出。最佳的方法是用cpu或者是操作系统提供的内存保护机制，这样一旦有任何的要对这块内存的操作指令，就会立刻break出来，这时再用gdb等的debug工具就可以直接查看调用栈找到元凶。较差的方法是定期或者是析构的时候监测，不过这样效果不好，只能知道到底有没有溢出，或者是哪块内存溢出。到底是谁干的，还是要大海捞针。 


栈内存：栈内存的混乱基本上会死的很直接，不会让问题慢慢的慢慢的变大。不过栈内存的特殊性，会导致他把案发现场的很多痕迹抹去，因为栈混乱了，所以你看到的调用栈完全是混乱的。你不知道出现的原因是什么。

对于这种情况，我暂时使用了一种看起来有点简陋的方法。就是使用一个buffer来手动的存储目前的调用栈。入栈的时候通过宏把函数名加入buffer，退栈的时候通过宏把函数名移除。坏处是增加了入栈出栈的代价，同时要记录的函数需要在开始和结束的时候添加宏。 


静态、全局内存混乱：这块是比较复杂的，特别是出现了这种内存的溢出，他会悄无声息的抹去你很多的全局，静态变量，但是系统依然可以运行，不过很多依赖于这些变量的行为都会变的无法预测，天知道这时候会做出什么变态的事情。同时这种内存的分配是在进入main之前发生的，我们完全无能为力。想要对付这种内存我建议。。。。。

在开发小组中规定。。。。不要使用这种内存。 




]]></description>
		<link>http://www.hlouis.com/develop/get-rid-of-memory-bugs/</link>
			</item>
	<item>
		<title>Test Live writer 2009</title>
		<description><![CDATA[同事帮我画的两张卡通头像，谢谢gary同学~
 
]]></description>
		<link>http://www.hlouis.com/diary/test-live-writer-2009/</link>
			</item>
	<item>
		<title>Fix IBus Openoffic and Awesome</title>
		<description><![CDATA[Add following line to soffice start script
# IBUS was confilict with OOO3 under awesomedon&#8217;t know why, but add the blow  
# line, everything OK then~ cheers
OOO_FORCE_DESKTOP=gnome export OOO_FORCE_DESKTOP 
]]></description>
		<link>http://www.hlouis.com/develop/linux/fix-ibus-openoffic-and-awesome/</link>
			</item>
	<item>
		<title>[ZT]Line feed and Carriage return</title>
		<description><![CDATA[今天，我总算搞清楚“回车”（carriage return）和“换行”（line feed）这两个概念的来历和区别了。
在计算机还没有出现之前，有一种叫做电传打字机（Teletype Model 33）的玩意，每秒钟可以打10个字符。但是它有一个问题，就是打完一行换行的时候，要用去0.2秒，正好可以打两个字符。要是在这0.2秒里面，又有新的字符传过来，那么这个字符将丢失。
于是，研制人员想了个办法解决这个问题，就是在每行后面加两个表示结束的字符。一个叫做“回车”，告诉打字机把打印头定位在左边界；另一个叫做“换行”，告诉打字机把纸向下移一行。
这就是“换行”和“回车”的来历，从它们的英语名字上也可以看出一二。
后来，计算机发明了，这两个概念也就被般到了计算机上。那时，存储器很贵，一些科学家认为在每行结尾加两个字符太浪费了，加一个就可以。于是，就出现了分歧。
Unix 系统里，每行结尾只有“&#60;换行&#62;”，即“\n”；Windows系统里面，每行结尾是“&#60;换行&#62;&#60;回车&#62;”，即“ \n\r”；Mac系统里，每行结尾是“&#60;回车&#62;”。一个直接后果是，Unix/Mac系统下的文件在Windows里打开的话，所有文字会变成一行；而Windows里的文件在Unix/Mac下打开的话，在每行的结尾可能会多出一个^M符号。
c语言编程时（windows系统）
\r 就是return 回到 本行 行首 这就会把这一行以前的输出 覆盖掉
如：
int main() {
cout &#60;&#60; &#8220;hahaha&#8220; &#60;&#60; &#8220;\r&#8220; &#60;&#60; &#8220;xixi&#8220; ;
}
最后只显示 xixi 而 hahaha 背覆盖了
\n 是回车＋换行 把光标 先移到 行首 然后换到下一行 也就是 下一行的行首拉
int main() {
cout &#60;&#60; &#8220;hahaha&#8220; &#60;&#60; &#8220;\n&#8220; &#60;&#60; &#8220;xixi&#8220; ;
}
则 显示
hahaha
xixi 
]]></description>
		<link>http://www.hlouis.com/diary/ztline-feed-and-carriage-return/</link>
			</item>
	<item>
		<title>Email to real letters</title>
		<description><![CDATA[Web 0.2 site, turn your email to real letters, charge U by letters count, you can choose the printing font style, or even you can let some people, real people write the letter for U!
]]></description>
		<link>http://www.hlouis.com/ideas/email-to-real-letters/</link>
			</item>
	<item>
		<title>Script RPC</title>
		<description><![CDATA[In c/c++ server design, event call always the painful part. How to register callback functions:

Use global or static method? 
Use event class and vritual method call?
How to handle the memory between caller and callee?
How to pass context, use pointer? use handle?

So many questions need to be taken care, but, maybe under the script world, life will [...]]]></description>
		<link>http://www.hlouis.com/design/script-rpc/</link>
			</item>
	<item>
		<title>SNS BBS way</title>
		<description><![CDATA[SNS和BBS每天累计着大量用户的活动，这些活动有很大一部分被沉淀下来成为有用的资讯。比如说怎么买电话卡，怎么做菜，又或者如何辅导孩子，某种型号的手机出了何种问题如何维修，如何给游戏机添加冷却装置。
这些积累都是SNS和BBS最有价值的部分，新用户往往是为了寻找这样的信息而进行注册和翻阅的。时间越悠久的社区这种有价值的信息就越多。然而我们的BBS和SNS几乎没有提供任何有用的工具帮助用户们来组织，保存分享这样的信息，而是依靠用户自己进行整理和归纳，唯一提供的功能大概就是“置顶”这个功能了。
如果SNS和BBS可以有效的整理归纳和更新这样的信息，肯定可以从中得到好处。让用户更加容易找到信息，可以扩大用户数量。将这些信息中提到的物品进行销售（比如水冷装置，或者某种食谱提及的配料）可以带来一定量的盈利。
]]></description>
		<link>http://www.hlouis.com/diary/sns-bbs-way/</link>
			</item>
	<item>
		<title>Hard work with Soft work</title>
		<description><![CDATA[前段时间转载过程序员的温情管理文化在 这篇文章中提出：
程序员是这样 一群家伙，他们可以把1000行代码写成10行，当然也可以把10行代码写成1000行。他们可以让这1000行代码比那10行容易看懂效率更高，也可以 让那10行比这1000行容易看懂效率更高。
我非常同意这样的看法，一个程序员如果在脑袋糊涂，精神萎靡的情况下写出代码 ，往往是逻辑不清楚，只是想把事情糊弄过去，久而久之，众多的小问题就积累起来，让整个项目陷入泥潭，并进入不得不重构的境地。
一个程序员，如果一天可以集中精力，进行5个小时以上的高效工作，并在这段时间内保持思路清楚，编写出高质量的代码，我觉得他肯定已经是顶级的程序员了，精力过人并且技术扎实。对于我们这样的正常人来说，一天可以维持三到四小时这样的高效工作就已经是很了不起的事情了。对于这段高效高质时间，我们应该加以充分的利用。对于效率偏低的时间，我们应该换一个策略来进行工作，这就是我想要说的，对于程序员的工作安排，应该有Hard word和Soft work的区分。
Hard work是指，列在工作项目上的，必须要做完的东西。这些工作项目都是列在整个开发项目的日程表上，不可或缺的环节。
Soft work是指，并没有列在整个项目的开发日程表上，但是对于技术储备，思路拓展都很有帮助的任务。进行Soft work应该可以让程序员enjoy其中，毕竟如果你对学习新技术没有兴趣，估计程序员的职业也就不适合你了。
对于项目的管理人员，挑战的任务就是如何分派两种任务，如何引导程序员进行Soft work，并控制这两种工作所需消耗的时间，如何帮助程序员了解并提高自己的高效工作时间，并可以让他们在早上打开电脑之后就能很明确的知道：今天的工作是什么，哪些最重要，哪些优先级别最高。
]]></description>
		<link>http://www.hlouis.com/design/hard-work-with-soft-work/</link>
			</item>
	<item>
		<title>你是否经常听到楼上有弹珠掉地上的声音？</title>
		<description><![CDATA[ 你是否经常听到楼上有弹珠掉地上的声音？


近来在互联网上看到，有人在网上做了一个调查，发现有80％的人听到过,每次都是2－3声象弹珠球跌落在地上又弹起的声音&#8230;
每次都是2－4声&#8230;.而且都是在半夜听到，声音好象还挺重的
现在的小朋友还玩弹珠吗？
并且有时还听到麻将骰子掉地的声音！
还有有时也可以听到好象一些家具搬动的声音，仿佛是人在拖一样！
以前还一直疑惑是什么原因，当时也并不怎么在意！没有深究其原因！但是通过互联网以后，发现很多朋友都似乎听到过这种来历不明的声音！！！这就奇怪了，全国各地难道都会出现这样的情形吗？？？这不是特别针对与个人的事情呀？
究竟是什么原因呢？是热膨冷缩吗？
实验一：真的跑去楼上打弹珠，发现声音根本几乎是听不到，其实地板比一般人想象中要厚得很多，顶多像文具、手表之类掉到地上的声音，如果这都听得到~那我看还得了，楼上一举一动你都听得到。
实验证明声音能否传到楼下和那个东西的重量有很大关系，也许这有声学或物理上的原因吧，在此就不探究了，总之就算刻意把弹珠很大力砸在地上~~也要夜深人静又很仔细听才听到一些(而且声音种类也不像)
实验二：一块1*1*0.17公尺的水泥块，内嵌钢筋网和两根水管
在实验室用压克力玻璃罩住里用热空气加热法；加到比室温高50度后持续90分钟，之后罩子打开浇冷水加吹风扇急速冷却，结果&#8230;&#8230;啥事也没发生~什么鬼声也没有.
实验三：同样水泥块同样步骤，这次用半虎钳+铁板把前后左右抵住卡紧；结果&#8230;&#8230;啥事又没发生~边缘有非常非常细的小小裂纹而已~什么鬼声也没有
那么~到底答案是什么??
原来元凶就是霉菌!!
是一种不完全菌纲的霉菌为主会腐蚀工业材料与水泥，好生于多细孔表面，以水泥中矿物质为食。
一般天花板是上下两层的细钢筋作支撑，在灌浆的时候其实钢筋不是笔直的被卡在水泥中，受到水泥浆的流动和重量可能会有向上或向左右的应力累积着，或着房子盖好数年后~受到地震或地基小位移等等因素，细钢筋又会产生新的应力。
在天花板的偏下层有电灯线路的管线出口，有温度与空气等等所以霉菌会沿着该孔开始逐步入侵水泥中缝细，细钢筋与水泥接触面是最理想缝细，霉菌多聚 生于此，菌丝向四周开始侵蚀成一个中空型管道。当某根有应力钢筋的周围水泥被侵蚀到一定程度后便会在中空管道中来回弹动，这就是弹珠声的来源。
所以实验下一步就刻意制作水泥块后；中间夹入比钢筋略粗的塑料棒形成中空道，水泥半干后拿出塑料管插入钢筋，再从另一端灌一些水泥固定。
事实证明，细钢筋在管道中弹动的声音和弹珠声是最像的。
这解释了以下几点
1.声音源不在墙内就在墙外，考虑许多人根本楼上无人住之类种种情形，且都是相似弹珠声；声音源必在墙内，墙内东西就是水泥、水管、钢筋、电线这四种，热帐冷缩已经排除，那这就是逻辑上唯一解释。
2. 既然多发生在下方钢筋网，所以都是听到从天花板传来，楼上要听到由地上传来可能当时要刚好耳贴近地板，这机率就小多了，因为事实证明厚水泥隔音效果比想象 中强，如果上方刚好放有大家具就更难听到了，且很少人天花板会贴东西，地板却常常贴有瓷砖或木头~更阻隔了声音传导。也许有人打地铺睡觉时运气好才会听到 吧。
3.这又解释了为什么几乎没人听过墙壁传出弹珠，因为隔间墙多半是砖墙根本没钢筋，机率就少太多，就算有；听到什么也会以为隔壁在钉东西。
]]></description>
		<link>http://www.hlouis.com/diary/strange-sound-in-night/</link>
			</item>
	<item>
		<title>[zt]程序员的温情管理文化</title>
		<description><![CDATA[作者：virushuo 发表于 2008-01-10 01:01 最后更新于 2008-01-10 01:01
版权声明：可以任意转载，转载时请务必以超链接形式标明文章原始出处和作者信息及本声明。
http://blog.devep.net/virushuo/2008/01/10/programmer-warmth-manage.html
 今天戴飞和我聊起来为什么在一些公司会很闲但是很累，在另外一些公司工作量大但是很开心的话题。不由得勾起了我总结一下长久以来关于工作，尤其是对程序员的工作管理的一些话题。从我带第一个技术团队算起，已经有很多年了。我始终坚持的一件事就是温情。所谓温情，很简单，替别人多想一些。我在附中的时候，下班总要“轰”大家回家，不让团队成员加班。如果为了躲避晚高峰不想走，我就鼓动他们玩玩游戏，看看电影看看书，别太累。
这事情在所谓“管理者”眼里是个笑话，在他们那里几个参数是等同的，加班＝＝工资＝＝产能。事实上每个工作过几年的人都知道这不可能。程序员是这样 一群家伙，他们可以把1000行代码写成10行，当然也可以把10行代码写成1000行。他们可以让这1000行代码比那10行容易看懂效率更高，也可以 让那10行比这1000行容易看懂效率更高。
在这种情况下，我更愿意在质量和工作量中找一个平衡点。即，不让任何一个人累着，不要让他们早晨起来躺在床上懒得上班，不要让他们因为加班被家人抱怨甚至感情危机。人首先是生活的人，如果放弃了生活，工作也没意义。皮之不存，毛将焉附？
最终找到的这种平衡点很有趣。那就是，程序员很难在一天内完成超过4个小时的高效工作。我说的是要求质量，有能动性，要动脑子，有创意的那种工作，拼贴代码那种机械工作咱们就不讨论了。因此我尝试在我和tiny的新公司实行每天6小时，每周30小时工作制。同时我们在力所能及的情况下不主动压低任何人的工资。我们不用期权引诱人，我们首先保证所有人生活正常，无压力，虽然我们认为我们的期权很值钱。但值钱不值钱这件事不是自己吹牛吹出来的，是大家共同努力出来的。
事实证明，每天6个小时工作时间不但没有降低效率，反而比8个小时高很多。想想也不奇怪，早晚放弃了1个小时，所有人都可以躲过早晚交通高峰，路上花费更少的时间，不会被人挤，心情不会太差，到公司可以很快进入工作状态，且心情轻松。
我倾向于相信，如果生活稳定，家庭幸福，收入正常，且在做一份有未来的事业，所有人都愿意尽自己最大努力。反之，其实所有人都有去稳定的大公司的机会。没人愿意来创业。
说到这里，一定会有人反驳：软件工程就是用来降低程序员不稳定性，工作量不够，产品质量不高的问题的。是的，这种说法完全对，不过仅限于外包领域。 外包领域具有明确的需求和验收标准，产品相当稳定。他们追求的是重复性，可复用性。因此他们希望通过一种机制，让程序员变成机器。一个程序员“坏了”（不 开心了，辞职了，老了精力下降了），那就换一个，就好像换掉一个巨大机器上面的齿轮，咔的一声，拧好螺丝，继续运转，一切都跟没发生过一样。刚才那个被拧 下的齿轮呢？老天，谁关心那个。
在互联网，尤其是带有较高技术含量的领域，或是新鲜的领域，我们因为没有标准可循，所以并不需要这种机器。我力图把程序员重新还原成人。所以我更喜 欢创造一个有温情的环境。其实不仅仅我这个小创业者的胡思乱想，google给员工极度的自由，极好的待遇，我觉得也可以看做这种思路。google知道 无法管理技术人员，所以他们干脆选择了彻底的，全面的妥协。一切都交给你们，你们努力去做就好，我们不给你压力。事实上，在选好人的情况下，这种思路产生 的产能是惊人的。当然，在中国似乎没选好人，所以产生的浪费也是惊人的。
几乎所有武术都在讲，出拳的时候手臂要放松，接触目标的瞬间发力，这样才有力量。如果出拳即发力，则会导致肌肉紧张，动作变形，最终你使出了全身的力气，却只打出了软绵绵的一拳。这多么的悲哀。
]]></description>
		<link>http://www.hlouis.com/diary/cheng-xu-yuan-guan-li/</link>
			</item>
	<item>
		<title>[ZT]MMORPG Server Design</title>
		<description><![CDATA[转载自 http://www.cppblog.com/Fox/archive/2007/12/16/38600.html
这篇文章转载自Fox的研究论文的开题报告，写的比较细致，和我目前所做得工作也比较相似。不过行文的水平比我高，把很多我说不明白的事情都表达了出来。很多具体的问题没还有深入，期待后续的文章



Author: Fox(yulefox@126.com)

一个MMORPG（Massively Multiplayer Online Role Playing Game）的架构包含客户端和服务器两部分。客户端主要涉及计算机图形学、物理学、多媒体技术等，服务器主要涉及网络通信技术、数据库技术，而人工智能、操作系统等计算机基础学科知识的应用体现在MMORPG开发过程中的方方面面。

一、游戏世界的划分
理想状态的游戏世界仅由一个完整的场景组成，在《魔兽争霸III》、《CS》这样的单机游戏中，所有玩家位于该场景中，在理论上，位于该场景中的任意玩家都可以看到游戏中所有玩家并与之交互，出于公平性和游戏性（而不是技术上）的考虑，游戏中并不会这样做。
然而，目前的MMORPG中，几乎没有任何一款可以做到整个游戏世界只包含一个场景，因为在一款MMORPG中，同时在线的玩家数量成百上千，甚至是数万人同时在一个游戏世界中交互。以现在的网络技术和计算机系统，还无法为这么多玩家的交互提供即时处理。因此，MMORPG的游戏世界被划分为大小不等、数量众多的场景，游戏服务器对于这些场景的处理分为分区和无缝两种。
在分区式服务器中，一个场景中的玩家无法看到另一个场景中的玩家，当玩家从一个场景到另外一个场景跨越时，都有一个数据转移和加载的过 程（尤其是从一个分区服务器跨越到另外一个服务器时），玩家都有一个等待的时间，在这段时间内，服务器的主要工作是实现跨越玩家数据的转移和加载以及后一 个场景中玩家、NPC等数据的传输，客户端的主要工作是实现新场景资源的加载和服务器通信。主要时 间的长短主要取决于后一个场景中资源数据的大小。分区式服务器的优点主要是各分区服务器保持相对独立，缺点是游戏空间不够大，而且，一旦某个分区服务器中 止服务，位于该服务器上的所有玩家将失去连接。
所谓无缝服务器，玩家几乎察觉不到场景之间的这种切换，在场景间没有物理上的屏障，对于玩家而言，众多场景构成了一个巨大的游戏世界。 场景之间，甚至服务器之间“没有了”明确的界线。因此，无缝服务器为玩家提供了更大的游戏空间和更友好的交互，实现了动态边界的无缝服务器甚至可以在某个 服务器中止服务时，按一定策略将负载动态分散到其他服务器。因此，无缝服务器在技术上要比分区服务器更加复杂。
目前国内上市的MMORPG，大多采用分区式服务器，做到无缝世界的主要有《完美世界》和《天下贰》等，国外的MMORPG中，像《魔兽世界》、《EVE》等，都实现了无缝世界。
无缝服务器与分区式服务器在技术上的主要区别是，当位于场景S1中的玩家P1处于两个（甚至更多）场景S1、S2的边界区域内时，要保证P1能够看到场景S2中建筑、玩家、NPC等可感知对象。而且边界区域的大小要大于等于P1可感知的范围，否则就可能发生S2中的可感知对象突然闪现在P1视野中的异常。
无疑，无缝世界为玩家提供了更人性化和更具魅力的用户体验。
二、无缝世界游戏服务器的整体架构
MMORPG的服务器架构从功能上主要划分为三种：
1、登录服务器（Login Server）
登录服务器用于玩家验证登录，并根据系统记录玩家信息得到其所在节点服务器，并通过世界服务器为登录玩家和对应节点服务器建立连接。
2、世界服务器（World Server）
世界服务器将整个游戏世界划分成不同场景，将所有场景按一定策略分配给节点服务器，并对节点服务器进行管理。世界服务器的另一功能是与 登录服务器交互。因此，世界服务器是登录服务器、节点服务器的沟通桥梁，当然，一旦玩家登录成功，世界服务器将主要处理节点服务器间的通信。因此，世界服 务器对于玩家是透明的。
3、节点服务器（Node Server）
节点服务器负责管理位于该节点的所有玩家、NPC的所有交互，在无缝世界游戏中，由于边界区域的存在，一个节点服务器甚至要处理相邻节点上位于边界区域的玩家和NPC的信息。
在具体实现上，不同的MMORPG为了便于管理，可能还会具有AI服务器、日志服务器、数据库缓存服务器、代理服务器等。
三、无缝世界游戏服务器的主要技术需求
1、编程语言（C/C++、SQL、Lua、Python）
2、图形库（Direct 3D、OpenGL）
3、网络通信（WinSock、BSD Socket，或者ACE）
4、消息、事件、多线程、GUI
5、OS
三、无缝世界游戏服务器需要解决的主要问题
1、资源管理
无论是服务器还是客户端，都涉及到大量资源：玩家数据、NPC数据、战斗公式、模型资源、通信资源等。当这些资源达到一定规模，其管理的难度不可忽视。而且，资源管理的好坏，直接关系到游戏的安全和生命。
2、网络安全
安全永远是第一位的，我们无法指望所有的玩家及其所持的客户端永远是友好的。事实上，威胁到游戏的公平性和安全性的大多数问题，归根结底，都是由于网络通信中存在的欺骗和攻击造成的，这些问题包含但不限于交易欺骗、物品复制。
3、逻辑安全
逻辑安全按理说应该是游戏中最基本的考虑，覆盖的范围也最广最杂。随机数系统是一个非常值得重视的问题，随机数不仅仅用于玩家可见的一 些任务系统、战斗公式、人工智能、物品得失等，还可用于网络报文加密等。因此，随机数系统本身的安全不容忽视。另外一个常见的逻辑安全是玩家的移动，最主 要的就是防止加速齿轮这样的变态操作。
4、负载均衡
MMORPG中的负载均衡包括客户端及服务器资源管理和逻辑处理的负载均衡，其中最难预知的是网络通信的负 载均衡，正常情况下的网络通信数量是可以在游戏设计时做出评估的，但因恶意攻击造成的网络负载是无法预测的。因此，负载均衡所要处理的主要是实时动态负载 均衡和灾难恢复。负载均衡需要解决的问题包括负载监控、负载分析、负载分发和灾难恢复。
5、录像系统
录像系统的构建，主要用于重现关键数据的输入输出，如玩家交易、玩家充值，或者当bug出现后，为逻辑服务器（泛指上文提到的所有类型服务器，主要是节点服务器）相应部分启动录像系统。待收集到足够数据后，通过录像系统重现bug。为了使逻辑服务器不受自身时间（如中断调试等）的影响，还可以专门设计心跳服务器来控制数据传输。
四、总结
在MMORPG中，真正的bug永远存在于将来。从这一点出发，关于MMORPG中游戏世界的构建，怎样苛刻的思考都不为过。
参考资料：
1、 [美] Kim Pallister编, 孟宪武 等译. 游戏编程精粹5, P467-474, P516. 人民邮电出版社, 2007年9月. 北京.
2、 [美] Thor Alexander编, 史晓明 译. 大型多人在线游戏开发, P174-185. 人民邮电出版社, 2006年12月. 北京.
3、 [美] Dante Treglia编, 张磊 译. 游戏编程精粹3, P117-122. 人民邮电出版社, 2003年7月. [...]]]></description>
		<link>http://www.hlouis.com/design/ztmmorpg-server-design/</link>
			</item>
	<item>
		<title>Flex SecurityError 2148</title>
		<description><![CDATA[Flex SecurityError: Error #2148 While Accessing local XML
So you’ve published your Flex application that accesses local XML, but when you try to run it outside of your Flex Builder folder, you might get a Flash Player Debugger error #2148. I ran into this problem while on a tight deadline, and am reposting here to get [...]]]></description>
		<link>http://www.hlouis.com/develop/flash-window/flex-securityerror-2148/</link>
			</item>
	<item>
		<title>Expose inside design</title>
		<description><![CDATA[有些时候，UI的一个设计准则就是将程序内部的设计结构暴露出来给用户，比如Mac系统上很流行的一个tap-to-run的程序，Quicksilver，一个基于键盘的程序启动软件，它的基本界面如下：

如上所见，左边是Quicksilver根据我让键入的字符在系统中寻找到的对象，右边就是针对这个对象所做的动作，用户可以使用默认动作或者是使用其他的动作。例如针对一个文本文件就有预览，打开等动作。
没有看过Quicksilver的代码，不过相信要我做一个这样的类似程序，我也一定会做这样的内部设计：
对象 &#8212; 动作
将对象和动作分别封装成两种最基础的类型，让他们之间有一定的属性可以互相交互从而形成关联。对于程序设计者来说，这个可能是最基础的想法。Quicksilver也忠实的将这个想法反应到UI上。程序设计师对于软件的理解肯定要比一般的使用者深入，如果我们能将一个好的设计暴露到UI上，往往可以给普通用户带来更好的体验。
]]></description>
		<link>http://www.hlouis.com/design/expose-inside-design/</link>
			</item>
	<item>
		<title>Game data server draft design</title>
		<description><![CDATA[游戏数据服务器是什么
数据服务器，一下简称DS，用来保存游戏中的数据，他存在与持久层之上，逻辑层之下，是一个针对逻辑层的数据持久层。
为什么需要这层
在我开发游戏服务器以来，发现的一个最严重的问题就是，游戏数据的安全和正确。对于游戏的数据我们大体可以分出一下两类：

临时数据：由游戏运行时生成，无需进行保存。在玩家下线或游戏服务器关闭之后就可以抛弃。
持久数据：游戏人物的数据、游戏中的物品，人物排名等等由玩家或服务器创造出的并有保存价值的数据

对于一款网络游戏来说，数据基本上是一切。玩家丢了数据等于是被盗号，运营商如果丢了很多玩家的数据基本上就无法正常的运营下去。对于数据可能出现的问题如下：

数据回档：档的原因多种多样， 大体有以下的原因：

服务器崩溃导致距离上次存档的数据没有保存
人物数据错乱，导致游戏无法将该玩家的数据保存（和数据库中的某些限制出现冲突）


数据存储效率低下，导致玩家存储数据的时间长于每次存储的间隙
游戏中的物品产生复制，在游戏中的交易的双方交易后出现某一方的回档，物品就会出现复制
数据保存复杂、危险，由于程序员的大量开发工作主要针对于服务器的逻辑，如果需要兼顾撰写保存数据的SQL，很可能出现问题

针对游戏服务器的数据的重要性和易错性，我觉得非常需要添加一层数据层，使游戏数据库对游戏服务器的逻辑透明，同时提供一些简单的方法保证数据的一致性。
具体要求
针对以上的分析，我觉得一个合格的DS需要做到一下的条目：

使SQL对使用者透明：
在这里我们假设，数据库的最终保存持久层依然是某种数据库，那么DS因该可以使用定义的数据类型自动生成保存，更新和读取的SQL语言。撰写逻辑的程序员，只需要定义数据类型和结构，完全不需要考虑和数据库的操作。数据库对于游戏逻辑程序员来说是完全透明的。
数据需要有权限概念：
第一个对某个数据进行访问的用户（其他的游戏逻辑服务器）是该数据的拥有者，拥有者可以限制其他访问者对该数据的权限，是否可读，是否可写等。同时拥有权可以放弃或移交。
支持对数据的原子操作：
对于交易等数据操作，可能需要同时更新两个以上的数据单元，这时候需要提供原子操作的支持，如果某个数据单元的更新不成功，就要让整个操作回滚。
DS本身的稳定以及自我恢复：
DS本身的逻辑应该足够简单，并保证服务稳定，内存占用合理并可以在配置文件中调整。DS如果发现持久层出现错误，比如无法连接到数据库，可以通知客户终止操作，并将当前DS内存的数据dump到本地文件，等待问题修正后可以重新Load到内存中。
多个DS的分布处理：
由于DS的内存和效率等的限制，对于一个游戏应用来说，一个DS可能无法承担所有的应用，需要考虑DS的分布处理。分布处理可能会涉及到很多细节，导致复杂度大大增加，希望有时间，我可以继续讨论这个问题。

]]></description>
		<link>http://www.hlouis.com/design/game-data-server-draft-design/</link>
			</item>
	<item>
		<title>Iptables: How-to Share your internet connection</title>
		<description><![CDATA[from  http://www.debuntu.org/iptables-how-to-share-your-internet-connection

   
iptables is a command line tool which allow system administrators to configure Linux packet filtering ruleset.
Using iptables, you are able to tweak packet filtering, Network Address Translation (NAT) and packet mangling which in the end are going to allow you to secure your server, share your Internet connection and log [...]]]></description>
		<link>http://www.hlouis.com/develop/linux/iptables-how-to-share-your-internet-connection/</link>
			</item>
</channel>
</rss>
