每位开发人员都应铭记的10句编程谚语

所谓谚语,就是用言简意赅、通俗易懂的方式传达人生箴言和普遍真理的话,它们能很好地帮助你处理生活和工作上的事情。也正因如此,我才整理了10句编程谚语,每位开发人员都应该铭记他们,武装自己。

1. 无风不起浪


别紧张,这也许只是一场消防演习

代码设计是否糟糕,从某些地方就可以看出来。比如:
a. 超大类或超大函数 b. 大片被注释的代码 c. 逻辑重复 d. If/else嵌套过深
程序员们通常称它们作代码异味(Code Smell),但是就我个人认为“代码警报”这个名字更为合适一些,因为它有更高的紧迫感的含义。根本问题处理不当,终将引火烧身。

译注:Code Smell中文译名一般为“代码异味”,或“代码味道”,它是提示代码中某个地方存在错误的一个暗示,开发人员可以通过这种smell(异味)在代码中追捕到问题。

2. 预防为主,治疗为辅

20世纪80年代,丰田公司的流水作业线因为它在缺陷预防方法上的革新变得出了名的高效。每个发现自己的部门有问题的成员都有权暂停生产。这个方法意在宁可发现问题后马上暂定生产、解决问题,也不能由其继续生产而导致更棘手且更高代价的修复/更换/召回后的问题。

程序员总会做出生产率就等同于快速编码的错误臆断。许多程序员都会不假思索地直接着手代码设计。可惜,这种Leeroy Jenkins式鲁莽的做法多会导致软件的开发过程变得很邋遢,拙劣的代码需要不断的监测和修改——也可能会被彻底地替换。最终,生产率所涉及到的因素就 不仅仅是写代码所消耗的时间了,还要有调试的时间。稍不留神就会“捡了芝麻丢了西瓜”。(因小失大。)

译注:Leeroy Jenkins 行为:WOW游戏中一位玩家不顾大家独身一人迎敌,导致灭团。

3. 不要孤注一掷 (过度依赖某人)

一个软件开发团队的公共要素(bus factor)是指那些会影响整个项目进程的核心开发人员的总数。比如某人被车撞了或某人生孩子或某人跳槽了,项目可能就会无序,甚至会搁置。

译注: bus factor 即指公共要素,比喻了开发过程中的一些共同因素。如果挤上 bus 的 factor 越多,bus 就越不稳定,所以要控制好 bus factor ,以免问题发生。

换句话说,如果你的团队突然失去了一个主力成员,你会怎么办?生意依旧进行还是戛然而止?

很不幸,大多数软件团队都陷入了后一种情况。这些团队把他们的开发员培养成了只会处理他们自己专业领域的“领域专家”。起初,这看起来是一个比较合理的方法。它 对汽车制造装配生产线很适用,但是为什么对软件开发团队就不行呢?毕竟,想让每个成员都掌握所编程序的细微差别也不太可能,对吧?

问题是开发人员不容易轻易替换掉。虽然当每位成员都可用时,“抽屉方法”很有效,但如果当“领域专家”突然因人事变动、疾病或突发事故而无法工作时,抽屉 方法立马土崩瓦解。(所以,)软件团队有一些看似多余实则重要的后备力量是至关重要。代码复查、结对编程和共有代码可用成功营造一个环境,在这个环境中, 每位开发人员至少表面上是熟悉自己非擅长领域之外的系统部分。

4. 种瓜得瓜,种豆得豆

《注重实效的程序员》一书中有这样一段话解释“破窗理论”:不要留着“破窗户”(低劣的设计、错误的决策或者糟糕的代码)不修。发现一个就修一个。如果没有足够的时间进行适当的修理,就先把它保留起来。或许你可 以把出问题的代码放到注释中,或是显示“未实现”消息,或用虚拟数据加以替代。采取一些措施,防止进一步的恶化。这表明局势尚在掌控之中。

我们见过整洁良好的系统在出现“破窗”之后立马崩溃。虽然促使软件崩溃的原因还有其他因素(我们将在其他地方接触到),但(对“破窗”)置之不理,肯定会更快地加速系统崩溃。

简而言之,好的代码会促生好的代码,糟糕的代码也会促生糟糕的代码。别低估了惯性的力量。没人想去整理糟糕的代码,同样没人想把完美的代码弄得一团糟。写好你的代码,它才更可能经得住时间的考验。

译注:《注重实效的程序员》,作者Andrew Hunt / David Thomas。该书直击编程陈地,穿过了软件开发中日益增长的规范和技术藩篱,对核心过程进行了审视――即根据需求,创建用户乐于接受的、可工作和易维护的 代码。本书包含的内容从个人责任到职业发展,直至保持代码灵活和易于改编重用的架构技术。从本书中将学到防止软件变质、消除复制知识的陷阱、编写灵活、动 态和易适应的代码、避免出现相同的设计、用契约、断言和异常对代码进行防护等内容。

译注:破窗理论(Broken Window theory):是关于环境对人们心理造成暗示性或诱导性影响的一种认识。“破窗效应”理论是指:如果有人打坏了一幢建筑物的窗户玻璃,而这扇窗户又得不到及时的维修,别人就可能受到某些暗示性的纵容去打烂更多的窗户。发现问题就要及时矫正和补救。

5. 欲速则不达

经理、客户和程序员正日益变得急躁。一切都需要做的事,都需要马上就做好。正因如此,快速修复问题变得非常急迫。

没时间对一个新功能进行适当的单元测试?好吧,你可以先完成一次测试运行,然后你就可以随时回来继续测试它。

当访问Y属性时,会不会碰到奇怪的对象引用错误?无论怎样,把代码放到try/catch语句块中。我们要钓到大鱼啦!

是不是似曾相识呢?这是因为我们在以前已经都做到了。并且在某些情况下、它是无可非议的。毕竟,我们有最后期限,还得满足客户和经理。但不要过于频繁操 作,否则你会发现你的代码不稳定,有很多热修复、逻辑重复、未测试的方案和错误处理。最后,你要么是把事情草草做完,要么是把事情好好做完。

6. 三思而后行

“敏捷开发”这个词最近被频繁滥用,经常被程序员用来掩饰他们在软件开发过程中的糟糕规划/设计阶段。我们是设计者,看到产品朝正当方向有实质进展,我们理应高兴。但意外的是,UML图和用例分析似乎并不能满足我们的愿望。所以,在不知自己做什么的情况下或者不知自己身处何处时,我们开发人员经常就稀里糊涂地写代码了。

这就好比你要去吃饭,但你根本没有想好去哪里吃。因为你太饿了,所以你迫不及待地找个餐馆,定个桌位。然后你上车开车后沿途在想(找地方吃饭)。只是,这样会耗费更多的时间,因为你要过较多的U型弯道,还在餐馆前停车,也许最后因等待时间过长而不吃了。确切地说,你最后应该能找到地方吃饭,但你可能 吃的饭并不是你想吃的,并且这样花费的时间,可能比你直接在想去的餐馆订餐所花的时间更长。

7. 如果你惟一的工具是一把锤子,你往往会把一切问题看成钉子


看见了吧?我早就说过动态记录在这个项目中很有效

程序员有一种倾向,当一谈到他们工具时,其视野就变狭窄了。一旦某种方法在我们的一个项目上“行得通”,我们就会在接下来所有的项目上都用到它。学习新东 西仿佛是一种煎熬,有时候甚至会心神不定。从始至终都在想“如果我用之前的方法做、这个就不会这么麻烦了”。一定要摒弃这种想法,按我们所知道的去做,即使那不是最完美的解决方法。

坚持自己所知很简单,不过从长远的角度讲,选择一个适合这项工作的工具要容易得多。否则,就会与你的职业生涯格格不入。

8. 沉默即赞同


我什么都没看见!没看见!

“破窗理论”与”变成惯性理论”有着宏观的联系。

编程社区就好像一个现实社区。每个作品都是一个开发者的缩影。糟糕的代码发布的越多,就越容易反映现状。如果你不去努力编写优秀、整洁和稳定的代码,那你每天都将和糟糕的代码相伴了。

同样地,如果你看到别人写出了糟糕的代码,你就要跟这个人提出来。注意,这时候机智就应该用上场了。一般情况下,程序员都愿意承认他们在软件开发中还是有不懂的地方,并且会感谢你的好意。互相帮助对大家都有利,而对问题视而不见,只会使问题一直存在。

9. 双鸟在林,不如一鸟在手 

如果可以讨论系统架构和重构,那么就差找个时间把事情做完。为了使正常运作的东西更加简洁而做改动,权衡改动的利弊很重要。当然了,简洁是一个理想目标, 但总会有可以通过重构改进的代码。在编程世界中,为了代码不过时,会频繁简单改动代码。但有时候你又必须保证代码对客户有价值。那么,你面临一个简单窘 境:你不能一石二鸟。你在重构旧代码上所发时间越多,你编写新代码的时间就越少。在及时改进代码和维护程序之间,也需要找到平衡点。

10. 能力越大,责任越大

毫无疑问,软件已成为我们生活中一个既基本又重要的一部分。正因如此,开发优秀软件格外重要。乒乓球游戏中的Bug是一回事,航天飞机导向系统或者航空交通管制系统中的Bug是另外一回事。Slashdot曾发表一文,讲述了单单Google News的一个小失误使一家公司股票蒸发11.4亿美元。其他例子参见《软件Bug引发的十次严重后果》。这些例子便说明了我们正行使着多大的权利。你今天写的代码,无论你是否有意,说不定有朝一日在重要的应用程序中派上用场,这想想都令人害怕。编写正确合格的代码吧!

译注:Slashdot是一个资讯科技网站。

总结一下网站注入与防范的方法

最近看到很多人的网站都被注入js,被iframe之类的。非常多。

本人曾接手过一个比较大的网站,被人家入侵了,要我收拾残局。。

1. 首先我会检查一下服务器配置,重新配置一次服务器安全,可以参考
http://hi.baidu.com/zzxap/blog/item/18180000ff921516738b6564.html

2. 其次,用麦咖啡自定义策略,即使网站程序有漏洞,别人也很难在文件上写入代码了。
参考自定义策略,有了这个策略,再烂的程序,你也无法写入我的文件
http://hi.baidu.com/zzxap/blog/item/efe093a7e0f2c190d04358ef.html

3. 可以用网络超级巡警删除被注入的JS代码。
参考
http://blog.csdn.net/zzxap/archive/2010/04/07/5459065.aspx

4. 如何批量删除数据库中被注入的代码?
在数据库查询分析器运行这段代码即可
SQL code :

DECLARE @fieldtype sysname
SET @fieldtype = ‘varchar’
–删除处理
DECLARE hCForEach CURSOR GLOBAL
FOR
SELECT N’update ‘+QUOTENAME(o.name)
+ N’ set ‘ + QUOTENAME(c.name) + N’ = replace(‘ + QUOTENAME(c.name) + ‘,”<script_src=http://ucmal.com/0.js> </script>”,””)’
FROM sysobjects o,syscolumns c,systypes t
WHERE o.id = c.id
ANDOBJECTPROPERTY(o.id,N’IsUserTable’)=1
AND c.xusertype = t.xusertype
AND t.name = @fieldtype
EXEC sp_MSforeach_Worker @command1 = N’?’

5. 创建一个触发器,只要有</script>就不给插入,对性能会有点影响
SQL code :

create trigger tr_table_insertupdate
on tablename
for insert,update
as
if exists (
select 1 from inserted
where data like ‘%</script>%’
)
begin
RAISERROR (‘不能修改或者添加’,16,1);
ROLLBACK TRANSACTION
end
go6. 最重要的还是程序的写法,用参数化SQL或存储过程
例如
C# code :

protected void cmdok_Click(object sender, EventArgs e)
{
//添加信息
StringBuilder  sql = new StringBuilder( ” insert into m_phone ( pid,PhoneName,num,price,phonetype,onSellTime,color,weight,Video,Camera,phoneSize,phoneSystem,Memorysize,PhoneDesc,Standbytime,ScreenSize,Frequency,InputMethod,Soundrecord,gps,fm,mp3,email,Infrared,game,clock,Calendar,Calculator,Bluetooth)  “);sql.Append(” values (@pid,@TextPhoneName,@Textnum,@Textprice,@Dropphonetype2,@TextonSellTime,@Textcolor,@Textweight “);

……………..

SqlParameter[] paras = { new SqlParameter(“@pid”, SqlDbType.Int, 4) ,
new SqlParameter(“@TextPhoneName”, SqlDbType.NVarChar, 50) ,
new SqlParameter(“@Textnum”, SqlDbType.Int, 4) ,
new SqlParameter(“@Textprice”, SqlDbType.Int, 4) ,
new SqlParameter(“@Dropphonetype2”, SqlDbType.VarChar, 20) ,
new SqlParameter(“@TextonSellTime”, SqlDbType.DateTime, 8) ,
new SqlParameter(“@Textcolor”, SqlDbType.VarChar, 20) ,
new SqlParameter(“@Textweight”, SqlDbType.NVarChar, 50) ,
………..
};
string[] stra = {Dropphonetype.SelectedValue,TextPhoneName.Text , Textnum.Text, Textprice.Text, Dropphonetype2.SelectedValue, TextonSellTime.Text, Textcolor.Text, Textweight.Text,
………….};

int a = stra.Length;
int j;

for ( j = 0; j < a; j++)
{
paras[j].Value = stra[j];
}
int strpid = 0;
string sqla = sql.ToString();
try
{
SqlHelper.ExcuteNonQurey(sqla, CommandType.Text, paras);//执行添加数据

strpid = Convert.ToInt32(SqlHelper.ExcuteSclare(sqla, CommandType.Text, paras));  //获取刚才插入的id号
}
catch (SqlException ex)
{
cmdreturn.Text = ex.Message.ToString();
}
cmdreturn.Text = strpid.ToString();
。。。。。。。。。

7. 通过URL传递的参数要用加密解密
C# code :

传输
string szTmp = “safdsfdsafdsfytrsd”;
szTmp = Server.UrlEncode(szTmp);
接收
STRING STRA = Server.UrlDecode(request.querystring(szTmp));

8. 把要使用的参数处理一下单引号,再放到SQL里面
例如 string stra=aa.replace(“‘”,”””)

用参数化SQL可以不用处理单引号
指定参数类型和过滤掉单引号,就可以杜绝99.9%入侵了

另外说一句:网上那些被人奉如圣经的过滤 update insert 等关键字的程序是用处不大的 upupdatedate 过滤掉 update还是update
还会造成不必要的麻烦

——摘自 CSDN论坛

Web开发人员应当知道的15个开源项目

如今,构建网站和开发Web应用程序已经不仅要求开发人员是一名优秀的程序员,更需要聪明的程序员。这也就是说,在可能的情况下,重复使用已有的代码和应用程序,而不是自己重头开始。

开源由来已久,并且很多网站的构建也使用了开源。开发人员都知道Linux、Apache、MySQL及 PHP (LAMP)。

但是除那些之外的其他开源项目呢?作为一名Web开发人员,你可以借助诸多可用的项目,以节省开发时间,或提高程序性能。

下面让我们看一下哪些开源项目可供大家免费使用。

可供使用的新型数据库

传统上讲,你可能习惯使用MySQL。尽管MySQL是一个非常棒的数据库,但诸多试图解决MySQL存在的问题的新型数据库已经问世。

1. MongoDB

MongoDB就是的“非关系型”数据库之一。它扩展性强、性能高。

2. Apache Cassandra

与MongoDB相似,Apache Cassandra也是一种“非关系型”数据库,它亦扩展性强、性能高。并且能够很好地处理庞大而活跃的数据集。(编注:Facebook用Cassandra来做邮箱搜索。)

更多

根据需要,你还有更多的选择。请参阅维基百科的这个列表

缓存数据

因为需要频繁使用一些数据,所以相比每次去数据库中查询,把这些数据存放在内存中更加合理。这能够大大提高Web应用程序的运行速度。

3. Memcached

Memcached是一种在内存中缓存小型数据块的简单但强大的解决方法。(编注: Facebook运行着成千上万的Memcached服务器,借以及时处理TB级的缓存数据。)

4. Redis

Redis的作用与Memcached相同,但包含更多的特性。例如,它也可以存储本应当永久性保存在磁盘上的数据。

加快网络请求的速度

大多数网站使用Apache的网络服务器来提供服务。它能够很好地服务于大多数网站,但是一旦网站的访问量增大,就需要做进一步优化。

5. Nginx

Nginx是一种与Apache非常相像的网络服务器,但它的速度相当快。作为负载平衡器,它常用于处理静态内容,如图像文件。

6. Varnish

Varnish是位于常规网络服务器之前的高速缓存器。它将所有热门内容放入内存,直接对其处理,无须将所有内容都传给网络服务器。(编注: Facebook用Varnish 处理图片和用户照片,每天都要处理十亿级的请求。Facebook所用到的其他开源项目,请参阅《揭秘Facebook背后的那些软件》一文。)

轻松管理内容

如果你在构建一个允许用户添加及编辑内容的网站,那么你可能需要一个内容管理系统(CMS)。CMS能够帮助开发人员轻松地管理博客及网站,并且提供大量的能够扩展网站功能的插件。

7. WordPress

虽然WordPress是个博客平台,但它也能用于管理大大小小的网站。

8. Drupal

Drupal是一个可用于构建强扩展性、高灵活性网站的完整平台。

更多

还有很多可用的内容管理系统。请参阅维基百科的这个大型列表

交互式的网络UI

如今,你可以使用JavaScript和AJAX技术,开发一个类似桌面应用程序那样的以多种方式运行的网络应用。使用JavaScript框架,能够轻松地开发大型的网络应用程序。

9. JQuery

JQuery是一个带插件的框架,这些插件有主构建包含AJAX交互及动画的动态网站。

10. MooTools

MooTools就和jQuery一样,是一个使用JavaScript构建强大网络应用程序的框架。

更多

如果你想尝试一下其他选择,请参考维基百科的这个列表

其他比较炫的资源

当你开始开发一个复杂的网络应用程序时,很多软件、库及模型能够帮你解决难题,如果不参考这些资源,你可能会花费大量的时间。以下是两个入门的例子。

11. Node.js

Node.js是一个事件驱动的输入/输出框架,支持用JavaScript编写应用程序,并在V8 JavaScript引擎上运行。这是一种开发快速、可扩展网络程序的很棒的方式。

12. RabbitMQ

RabbitMQ是一种可靠的、可扩展的信息传送系统,它能够处理高吞吐量。如果需要在系统之间或应用程序之间交换数据,比起传统的解决方案或直接将数据存储在数据库中,信息传送系统的更能胜任这一工作。

使用框架来加速开发进程

不管你是使用PHP还是其他的编程语言,有很多不同的可用框架能够帮助你加速开发进程,并能够更加轻松地管理代码。

13. Symfony

Symfony是一个PHP框架,它包含很多能够加速开发复杂网络应用程序的组件及工具。同时它包含社区提供的1000多个插件。

14. Ruby on Rails

对Ruby语言而言,Ruby on Rails是最流行的可用框架。

15. Django

Django是一个Python网络框架,它用来帮助快速开发高性能、优秀的网络应用程序。

更多

维基百科上有一份更完整的列表,这个列表包含不同语言的可用网络应用框架。

后话 – 合理利用时间

开发人员有必要花费时间不断了解哪些新软件是可用的,这样对轻松地解决复杂的任务大有裨益。

而且在项目开发之初,花费一些时间做计划和调查也是非常有必要的,因为这样可以明确即将面临的问题,并确定其最佳解决方案。

自己编程来解决每个问题的时代已经结束,如今更多的是灵活使用现有技术来解决问题。

不知正在看本文的Web开发人员,在上述这些开源项目中,你用到了哪些?欢迎你在评论中分享你的使用经验和心得。

程序员从初级到中级10个秘诀

Justin James曾发表过一篇博文《10 tips for advancing from a beginner to an intermediate developer》,为我们分享如何才能完成程序员从初级到中级的蜕变,现将中文译文转载于此,供大家借鉴。 在一封与TechRepublic会员交流的邮件当中,他提到了面向程序员的博客、文章及杂志分成两类:面向初学者类(“hello world”这种类型的教程)以及面向专家类(MSDN杂志)。这个观点很好,有关程序员如何从初级跃升到中级的信息极少。以下是为了实现这种转变需要你去做的10件事。

1.学习另一门语言 其实你学的是哪一门语言并没有关系,但是学习另一门语言(不管你已经了解多少种语言)将把你打造为更好的程序员。能学会一门与你日常使用的语言风格迥异的 语言则更佳。打个比方,如果你是C#程序员,学习VB.NET或者Java对你的帮助就没有学习Ruby或者Groovy大。 我说“学另一门语言”的意思是要真正学会它。学习一门语言包括三个领域的知识:语法、内置操作符和库,以及“如何使用”。前面两个简单;我认为一名有经验 的程序员,根据语言的不同,能在半小时到几小时内掌握足以维护代码的语法知识。操作符和库只不过是知识逐步积累的过程,你什么时候想清楚要了解什么了,再 去查阅参考材料也不迟。只有第三项,“如何使用它”-要花上你几个月的时间去跟这门语言打交道,真正的奇迹就在此发生。我建议用这门语言的风格去做一个适 合该语言的项目。 真正学会了另一门语言之后,我敢保证你的程序员水平一定会突飞猛进。

2.学习先进的搜索技术、手段和及策略 作为一名好的程序员,不仅仅是技能的问题了,而是你寻找信息的技巧,这个趋势越来越明显。对大部分人而言,仅仅输入“现代语言及开发框架”,这都是泛泛之 谈,记不住多少的。因此,你完成工作的能力通常取决于你的检索能力。不幸的是,了解到如何找到准确而高质量的信息可不仅仅是跑到TechRepublic 来找答案,或者在你选好的搜索引擎上敲几个字那么简单。 “技术(Techniques)”、“手段(tactics)”和“策略(strategies)”看起来是一回事,实际上并非如此。你需要学会的技术是 掌握你喜爱的搜索引擎的高级搜索系统;你需要了解诸如布尔操作符,如何过滤结果(像“非”关键字,域限制等等),关键字的词序扮演什么角色,等等。一句 话,RTFM(Read The Fucking Manual,读那些他妈的手册)吧。 你应该学会这些手段,诸如如何接近特定的搜索,以及了解自己实际上想查些什么。查错误很容易—只需查出错代码即可—但是许多搜索的关键字选择要困难得多。 至于策略,你需要学会的东西,包括像应该使用哪种搜索引擎(提示:普通的搜索引擎不一定就是最佳选择),使用普通搜索引擎前应该访问哪个网站,甚至是应该 到哪个论坛去寻求帮助,等等。

3.帮助别人 教别人始终是学习一切东西的最好方法之一。相对而言,由于你在开发领域还是个新手,认为自己没什么可教给人家的,这可以理解。但这毫无意义。记住,你所学 到的一切都是你从别人或别处学到的;因此请尝试一下,成为另外一个人要请教的“别人”。每天尽量花一点时间试着回答TechRepublic上的问题,其 他网站的亦可。读读其他会员的回答,你也可以学到很多东西。

4.有耐心,常练习 研究表明,要成为一名“专家”,需要花费10年,或者10000到20000小时的刻意练习时间。真的很久。还有,成为专家不尽然就是执行10年同样的任 务;通常这意味着要在特定领域内执行广泛的任务。需要花费大量的时间和精力才能成为“专家”;做几年程序员是不够的。想在30岁左右成为一名高级软件开发 工程师?要么尽早接受教育/培训,要么你得愿意在闲暇时间进行大量的工作、阅读和练习。我从高中开始编程,还牺牲了许多休息时间去跟踪行业发展、学习新技 能等等。结果,我获得中级和高级程序员的时间就比我的大部分同事都要早得多,随着时间的推移,这些就转化成为很多的金钱。

5.对教条拒之门外 是时候开诚布公了:也许初级程序员了解的东西还不足以说出做某件事情有一种最好的方式。尊重朋友或者权威的观点是好的,但直到你更有经验之前,不要把他们 的观点说成是你自己的。很简单,如果你所了解的不足以让你独立地找出这些东西来,你又怎么会认为你知道哪一位“专家”是对的呢?话是难听了点,不过请相信 我;由于受某些愚蠢建议的蛊惑,或者追随某些根本不知道自己在说些什么的所谓专家,白白把自己的职业生涯耽搁了几年,这样毛头小伙程序员,我见过多了。这 一点有一个很好的例子,就是面向对象结构的滥用。比如说,许多初级者读了一些有关面向对象的信息后,突然间,他们那简单的应用程序的类图看起来就像埃菲尔 铁塔一样了。

6.深入学习一点先进理念 成为一名中级程序员,很大一部分是要在代码里面体现出一些所擅长的概念。就我而言,是多线程/并行性,是正则表达式,以及如何对动态语言进行变化(后两个 在我离Perl渐行渐远后开始退化)。这是如何发生的?多线程和并行处理是因为我读了相关文章,觉得它看起来很有趣,然后再自己把它弄清楚了;然后我就一 直使用这些技术来写应用。我做过一件工作,是用Perl写的,里面运用了大量的正则表达式。我也用一个过程引擎模板和内置数据库系统写过我自己的电子商务 引擎;那时我几乎花了2年时间在这上面。 找到真正令你着迷的东西。也许是图像处理,也许是数据库设计,等等。即便你是一个入门级的程序员,也要尝试一下成为某一自己所关注领域的专家。这会让你相 当快速地进入到中级水平,一旦你到了那个水平,你的专家之路也走到一半了。

7.学习你的领域里面的基本理论 写出“Hello World”,跟理解那些字是如何显示到屏幕上的是两码事。通过学习支撑你所从事的工作的“基础/底层工作(groundwork)”,你会变得更加在 行。为什么?因为你会理解事物为何会以这种方式运作,当东西坏了就能知道是哪里的问题,等等。通过掌握工作的底层机制,你变会得更出色。 如果你是Web程序员,读读HTTP RFC和HTML规范。如果你使用代码生成器,好好看看它生成的代码;如果你使用数据库工具,看看它生成的底层SQL语句,不一而足。

8.看看高级程序员的代码 在工作中看看高级程序员写的代码,然后问一问事情是如何以某种特别的方式完成的,为什么?可能的话看看开源的项目。甚至即使其他程序员没有最好的编程习 惯,你也会学到许多编程经验。当然,要小心别学到坏习惯。我的意思是说不要生搬硬套人家的东西;你要能领会到哪些是能行的通的,哪些是有道理的,然后再模 仿人家。

9.学习好的习惯 愚蠢的变量名,糟糕的缩进习惯以及其他一些凌乱的迹象就是一个没有经验的程序员的最好标记。一个程序员在学会如何编程时,却经常没有被传授到那些不那么有 趣的细节,像代码格式编排。甚至尽管学习这些东西并不会令你的代码更好,也不会令你成为更好的程序员,它也会确保你不被同事视为入门级的程序员。甚至即使 某人是高级程序员,如果他的变量是以他那97只猫的名字来命名,或者其函数叫做“doSomething()”的,他们看起来也不像是知道自己在干什么的 人。而且会令其代码在过程中更难以维护。

10.要玩的开心 想要痴迷于单调乏味的工作?痛恨工作吧。要想升级为中级程序员可不仅仅是为了拿到不断增长的工资不达目的誓不罢休,而是要真正享受工作。如果你不喜欢自己 的工作,且还是初级程序员,你怎么会认为成为中级或高级程序员情况就会有所好转呢?换工作或改职业吧。反过来说,如果你喜爱所从事的工作,那就好!只要你 坚持下去,我保证你能成为一名更好的程序员。(Justin James)

Serv-U 用户配置文件的加密与解密

摘要:先看ServU密码加密存储方法 首先随机生成2位字符(从a-z小写字符),再将用户原始密码与这2位随机字符合并成为新的密码字符。 如:用户原始密码为a,随机生成字符为dx,则合并后新的密码字符串为:dxa 再使用新密码字符串进行MD5Hash运算. dxa = F2319AE3B312103BB…

 

先看ServU密码加密存储方法
首先随机生成2位字符(从a-z小写字符),再将用户原始密码与这2位随机字符合并成为新的密码字符。

如:用户原始密码为a,随机生成字符为dx,则合并后新的密码字符串为:”dxa”
再使用新密码字符串进行MD5Hash运算.
dxa=F2319AE3B312103BB3259CA8242DD16C
然后再存储到ini文件,存储方法为2位随机字符加上新密码字符的MD5Hash值.
如下:
[USER=a|1]  Password=dxF2319AE3B312103BB3259CA8242DD16C

ServU密码破解方法:

除去前2位随机字符获得F2319AE3B312103BB3259CA8242DD16C
然后去查询MD5的网站上面查询F2319AE3B312103BB3259CA8242DD16C

查出来的密码前两位肯定是dx,把dx去掉即是真正的密码

10款优秀的替代操作系统

在世界的某一个角落,有人正在开发或许会改变未来的操作系统,它们可能会成为我们生活中缺一不可的东西,让人产生缺少它就活不下去的感觉。Techradar介绍了10款优秀的替代操作系统,它们没有大型企业为后盾,多由社区的开发者业余开发。

主流的操作系统来自微软、苹果和Linux,替代操作系统包括了: 处于早期开发阶段的GNU/HURD,主要用Java语言开发的JNode,工业级操作系统FreeVMS,类主机界面的DexOS,分布式操作系统Inferno,汇编语言开发的操作系统KolibriOS,OpenBSD,Amiga 研究操作系统AROS,开源Windows兼容系统ReactOS,开源BeOS系统Haiku(前称OpenBeOS)。

程序员那些悲催的事儿

在StakeOverflow上有这样一个贴子叫“Confessions of your worst WTF moment”(WTF就是What the fuck的缩写),挺有意思的,我摘几个小故事过来,希望大家在笑过之后能从中学到什么——所有的经验都是从错误中来的(我在其中加了一些点评)

 

我们公司的软件是给警察局用的,那是一个对用来处理被逮捕的人的系统,此系统还需要收集脸部特征和指纹信息,并且,这个系统和会向FBI的系统提交这些信息。当我们在测试这个系统的时候,我们一般都是用我们自己的指纹,当然,数据库联着的是我们的测试数据库。不过,有一次,在我们测试完后,我们忘了把系统切换回生产库,于是我们的测试数据库就联上了生产环境,于是我们的指纹信息和照片就散布到了其它系统中……清除我们警察局这边的还好办,但是,你需要波士顿警察局警司去法院签字才能从FBI的数据库中清除我们的信息。

点评:测试环境和生产环境的数据不要混在一起。

有一次,我需要向新系统中导入一堆数据,因为数据量太大,需要5个小时,只能在夜里来干,在系统需要正式使用前2个小时,数据导完了,此时是凌晨4点。随后,我需要删除一些数据,于是我在SQL命令地上输入了“DELETE from important_table; where id=4”。是的,我没有看到哪里还有个分号,天啊。

点评:这就是加班工作的恶果。另,在delete之前最好先做一次select。

我把我的管理员口令提交到了一个开源软件的源码里。

点评:1)版本管理器里的东西是删不掉的。2)一些用户和口令要hard code在代码里,所以,不要混用代码使用的权限和管理员的权限,小心管理程序的运行权限,为其注册专门的用户。

 

我为一个很大的银行开发软件,在我的代码里,我为一段理论上根本不可能执行到的代码加了一个报错信息。有一天,不可思异的事发生了,这条报错信息显示在了该银行的1800个分行的超过10000个终端上——“如果你看到这个信息,说明整个系统被Fuck了,回家吧,祝你过得愉快!”

点评:“假设是恶魔”,Assume意为Ass – u – me,意为——搞砸你和我。对于一些关键东西,永远不要做假设。小心你言语中的——“可能、应该、觉得、不应该”等词语,程序可不认这些东西。

我远程登录到服务器上加几个防火墙规则。第一件我想干的事是在不允许任何人的任何连接,第二件是,为某个端口打开访问权限。不过,我在做完第一件事后就把配置保存了,结果其生效了……

点评:这样的事经常发生,做远程网络管理的人多少会有那么几次发生这样的错误。在你将你的网络配置生效前,你得想一想,断线了你是否还能登得上去。改配置不要太冲动,生效前检查几次。

我们的代码中有一个模块完美地工作了很多年了,只是代码太乱了。我说服了我的老板,我可以重写这个模块,于是我花了三个星期来重写这个模块。今天 ,我还记得,我的老板站在我的后面看着我,而我在在流着斗大的法汗珠去fix被我重写的“超级漂亮”的那个模块中一个接一个的bug。从那以后,我再也不重写代码了,除非有重大的利益。

点评:这就所谓的屠宰式编程。这个案例告诉我们两个道理,1)维护代码要用最最最保守的方法来进行。2)重构代码前要像一个商人一样学会计算利益。当然,ThoughtWorks的咨询师一定会告诉你TDD,结对,极限等等方法告诉你如果实践重构。但我想告诉你,一个程序在生产环境里运行好几个年能没有问题是一件很不容易的事,那怕其中的代码再烂,你再看不过去,你都要有一个清醒的头脑明白这几点,1)软件的运行质量是远远大于代码质量的,2)你的测试案例是远远小于生产环境的,3)软件的完美的质量,是靠长时间的运行、测试和错误堆出来的,而不是某种方法论

————————————————

相信大家做程序员这一生中也有很多发生在自己身上的悲催的事儿,欢迎分享。我先分享几个我亲身经历过的事。

一个发生在我的领导身上。

我98年刚参加工作的时候,在某单位网络部门,一次,我们整个部门去给下属单位培训Cisco路由器,结果我们发现带去培训地点的设备少带了集线器HUB,设备连不起来。于是领导很不高兴,质问我们为什么没有带集线器?那几个对领导平时就不满的老员工说办公室里没有集线器了,都借给别的部门了。领导想了想,问我:“陈皓,我记得上次我给过你个集线器”,我说,“好像没有吧,我记不起来了,什么牌的?几口的?”,领导说: “什么牌子想不起来了,不过我记得那个集线器是一个口的”。“一个口的?!”,我心里嘀咕着,“真敢说啊”。但我不敢接话了。那几个老员工来劲了——“哪有一个口的HUB啊,一个口的怎么联两台电脑啊?”,领导说:“用两个一个口的不就行了”。领导这话一出,全场一片寂静,无言以对……

后来:我们所有的组员都离开了我们的这个领导,我们的这个领导今天还在那里工作。我想告诉大家,很多时候该走的是领导(包括外企,我上一东家正在裁人,不过我觉得该被裁掉的应该是那些经理)。我们的领导经常出这样或那样的笑话,这让我随时随地地警醒自己——“不要当一个被人笑话的经理”,于是,今天我还在努力地学习技术。

另一个发生在我身上

刚刚接触Linux的时候,还不是很懂,那时的PC还只有奔3,编译公司的程序好慢啊,有时候为了调查一个问题,需要不断地打log,来来回回地编译,很不爽。直到有一天,硬盘不够了,df一下,发现/dev/shm还有空间。于是,把全部程序copy了过去,发现编译起程序超快无比,爽得不行。于是就把工作环境放在/dev/shm下了,连开发都放在这里了。这一天,开发一个功能,改了十来个文件,加班很晚,觉得基本搞定,大喜,回家睡觉。第二天一来,发现/dev/shm下空了,一个文件都没有了,问同事,同事不知,同事还安慰我说,上次他的文件也不知道被 谁删了,于是我大怒,告老板!老板也怒,发邮件到整个公司质问大家谁删了陈皓的程序,无人应答。IT部门答,“昨晚唯一的操作就是重启了linux服务器,什么也没干,不过我们天天备份服务器,可以恢复”,IT部门问我丢的文件在哪个目录下?于是,我reply to all – “在/dev/shm下……”,哎,人丢大发了……

后来:我很感谢我以前犯的这个错,从那天以后,我开始立志学好Linux,这个错误让我努力,让我发奋。所以,我想告诉大家——尤其是刚出道的程序员,你们要多多犯错,要犯错那种丢死人的错,这样你才会知耻而勇

再来一个发生在我同事身上的

01年,我们开发银行系统,在AIX上开发,RICS6000很贵,只能在客户那里开发,开发进度很紧张,慢慢地硬盘就不够用了,系统中有大量的垃圾文件,于是需要清除一些文件,于是有一个同事写了一个脚本,可以自动清除的各种不重要的文件,里面有一条命令大致是这个样子“ rm -rf ${app_log_dir}/*”,意为清除程序运行的日志。为了使用这个脚本,需要在root用户下运行,一开始还不错。直到有一天,某人一运行,整个根就没了。搞得整个团队只能用一周前的备份重写已写好的代码。后来,才发现原因是${app_log_dir}变量为空,于是成了“rm -rf /*”……

后来:这个事后,我的那个同事,把rm命令改了名,并自己写了一个rm命令,把删除的文件先放到一个临时目录下。而我也因为这个事情,到今天,每次当我在root目录下使用rm时,敲击回车的手都是抖的。(另,rm时永远使用绝对路径)这里,我想告诉大家——犯错不可怕,可怕的是不会从中总结教训,同一个错犯两次

欢迎分享发生在你身上那些悲催的事。

明星软件工程师的10种特质

如今,每家公司都似乎成了科技公司。从软件创业公司到投机性投资公司、制药巨头和媒体巨头,它们都越来越多地加入到软件业务行列。代码质量不仅成为了一个必需品,更成为了一个竞争优势。因为众多公司围绕软件而竞争,开发软件的人——软件工程师正显得越发重要。但是,你该如何发现那种百里挑一的程序员呢?在本文中,我们简明扼要地列出了明星开发人员的10种特质。

 

1. 热爱编程 2. 完成事情 3. 持续重构代码 4. 使用设计模式 5. 编写测试 6. 善用现有代码 7. 专注可用性 8. 编写可维护的代码 9. 能用任何语言编程 10. 知晓基本的计算机科学
1. 热爱编程

编程是一种为了满足兴趣而心甘情愿去做的劳动(Programming is a labor of love)。和其他任何职业一样,唯有真正的热情,才能完成真正的伟大事情。这里有个误解,认为编写代码是机械化并纯科学性的。事实上,最优秀的软件工程 师是工匠,他们能把能量、独创性和创造力融入到每一行代码中。伟大的工程师知道何时该把代码雕琢至完美,知道何时把大型系统像拼图一样组装到一块。热爱编 程的工程师从构建软件中获得满足,就好比一位作曲家在完成一部交响乐后而欣喜若狂。正是兴奋感和成就感,才造就了喜爱编程的明星工程师。

2. 完成事情

有很多技术人员只谈论软件而不编写代码(只说不做型)。而伟大软件工程师会真正去编码,这也是他们最为重要的品质之一。他们是实际做事的人。聪明人都 知道,解决问题的最佳途径是直面问题,而不是花上数周来设计复杂又不必要的架构和函数库。优秀工程师应当会问:解决手头问题的最简单方法是什么?最近的软 件开发方法——敏捷实践,正是专注那个。它的思想是,把复杂的项目拆分为短小的迭代,每个迭代只关注一小部分的增量功能。因为每个迭代对应的编码只需要数 周,所以功能易于管理并简单。

3. 持续重构代码

编码很像雕刻。要像艺术家一样不断完善自己的作品,软件工程师也要通过可能的最佳方式来持续完善自己的代码,以达到目标。重新塑造代码的原则称为“重 构”,Martin Fowler在他的创意书中有相应描述。重构背后的原始思想是:改善代码而不改变其功能,移动调整部分代码以确保系统不腐,还有确保系统完成基于当前需求 该完成的事。持续重构可以让开发人员解决另一个著名的问题——“黑盒遗留代码”(这个问题基本无人想触及)。

几十年的软件开发文化要求我们,不应该去改变正常工作的东西。然而,随着时间推移,问题是我们成为了老旧代码的奴隶,老旧代码变得不稳定和不兼容。而 重构正好可以改变这一状况,因为我们是代码的主人,不是它的奴隶。重构在工程师和代码之间建立起持续的“对话”,并带来所有权、确定性、自信心和系统的稳 定性。

千万不要成为老旧代码的奴隶。如果代码是他人所写,或许你可以轻易推脱责任。但大多数时候,那些代码是自己所写,要拿得起放得下,旧代码该埋时,就把它埋了!

4. 使用设计模式

自从所谓的“四人帮”(Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides)发表他们的著作——《设计模式》后,全世界的软件工程师一直都在讨论模式。在我们所处世界,不管是自然界还是人类行为,模式无处不 在。软件工程自然也不例外。模式就是不断重现的跨语言跨系统的场景和机制。一位优秀的工程师通常能识别并利用模式,而不是受制于模式。工程师不应(强制) 让系统去适应某种模式,而需发现在系统中使用模式的时机(恰当使用模式)。在使用模式来确保正确性时,应借鉴利用前人的智慧结晶,使用以前能正当解决特定 工程问题的方法。但请切记:模式不是万灵药;不要为了使用设计模式而使用设计模式。

5. 编写测试

曾有段时间,软件工程师们认为测试不值得他们去做。然而,如果你不做测试,你怎么能确保代码就能正常工作呢?敏捷实践中的“单元测试”已获得普遍认 可,因为它注重编写测试来反映代码是否有效。随着系统增大,测试也随之增大。有经验的工程师知道并了解测试的价值所在,因为测试的目的就是创建一个能正常 运作的系统。优秀的工程师通常会确保出现过一次的Bug不会再出现第二次。但优秀的工程师也知道,不应该浪费时间写那些琐碎或多余的测试,而需要专注测试 各个组件中的核心部分。

6. 善用现有代码 

“重新发明轮子”一直是软件行业中的巨大问题之一。从发明新语言到从写函数库,忽视并重写那些已经存在并已能工作的奇怪驱动力,已经造成大量软件开发 的失败案例。一位明星工程师会专注三种基本类型的重用:第一,内部基础架构的重用,相应代码是他自己或同事编写的;第二,使用第三方的函数库,比如 JDK。最后,研究使用某些大型网络服务商提供的相应服务,比如Amazon。总之,正确善用现有的代码,使得软件工程师能真正专注于最为重要的事情上 ——应用程序本身。

7. 专注可用性 

优秀的工程师通常都专注于用户。无论用户是企业还是个人,无论是为消费型的软件公司还是投资银行,需要关注的都是可用性。用户如何和系统交互?系统是 否提供一种简单、直接和平稳的操作体验?有种说法,因为软件工程师是技术人员,他/她和“用户如何与系统交互”没有关联,这种说法严重错误。优秀工程师努 力工作是为了什么?不正是让系统简单并易于使用。他们无时无刻都会想到用户,不会尝试去发明那些令人费解,只有极客才能理解并欣赏的东西。

有些时候,一些软件工程师过于投入,反而忘记所编写的程序/软件,是供他人使用,不是做给自己看的“艺术品”。所以,在软件开发过程中,一直要把“用户”放在心中。

8. 编写可维护的代码

软件开发界的另外一个小秘密是:编写优秀代码和糟糕代码所花费的时间是一样多。一位训练有素的工程师,他/她会从第一行代码开始就考虑可维护性和代码 的演化。没有任何理由编写“丑陋”的代码、长达数页的函数,或是稀奇古怪的变量名。优秀的工程师编写代码会遵循命名惯例,代码编写紧凑、简单和不过度炫耀 聪明。代码的每一行,都应恰如其分地展现出其原有目的。在给不便理解的代码(块)合理注释时,别忘了命名规则。清晰明了的函数名和变量名可以让代码不言而 明。

在编码时,有些程序员会有这种心态:过一会儿再来修改或完善某部分代码或某条语句。但谁知这一“过一会”竟然是“一天”、“一周”、“一个月”或“一 年”,甚至以后根本就没机会再回头修改。所以,尽量别妥协写出暂时堪用的代码。否则,不仅不会节省开发时间,也可以阻碍整个进程。当然也不利于后续维护人 员的工作。

9. 能用任何语言编程

优秀的软件工程师活血有自己一门特别钟爱的编程语言,但从不会执迷于当中。如今已有很多优秀的编程语言,也就是说,如果你只会使用其中一门语言,说明 你缺乏多样性。你可以用Java、C#或C++编写任何现代软件,可以用PHP、Perl或Ruby编写任何网站的后台。简而言之,编程所用语言,远远没 有语言相应的函数库重要。优秀的工程师能够认知到这一点,并愿意去学习新语言、新函数库和构建系统的新方法。

10. 知晓基本的计算机科学知识

最后,但肯定不是优秀工程师最不重要的特质就是:扎实的基础。优秀的工程师或许并没有计算机科学的学位,但他/她必须知道基础——数据结构和算法。如 果不知道哈希表,或者不知道链表和数组之间的差别,你如何构建一款大型的软件?。这些都是每位从事软件开发的开发人员应当知道的。算法也同样重要,从二分 查找到各种排序,到图形遍历,一位明星工程师必须知道并内在消化这些基础东西。因为这些基础就是你在构建任何现代软件中做抉择时的必备品。

结束语

以上就是区分伟大软件工程师的诸多特质。其中讨论的“热情”,是非常重要的。代码重用、设计模式、基础数据结构和算法都是必须知道的,而敏捷实践中的重构和单元测试则有助于工程师应对复杂的软件。尤为重要的是,明星工程师相信简洁和常识。也正是这些信念,帮助他们成功构建当今世界所需的看似不可能又错综复杂的系统。

引用网上看到的一段话:对于知识,要求知若渴;对于自己,要虚怀若谷。保持开放的心态,保持孩童般的好奇心看待新鲜事物。当今世界,日新月异,不仅要从书中获取知识,更要尽可能从其他途径来学习经验和知识,在求知过程中,《请谨记5件事,做一名快速的学习者》。

——摘自 cnBeta

URL的井号

去年9月,twitter改版。

一个显著变化,就是URL加入了”#!”符号。比如,改版前的用户主页网址为

http://twitter.com/username

改版后,就变成了

http://twitter.com/#!/username

在我印象中,这是主流网站第一次将”#”大规模用于直接与用户交互的关键URL中。这表明井号(Hash)的作用正在被重新认识。本文根据HttpWatch的文章,整理与井号有关的所有重要知识点。

一、#的涵义

#代表网页中的一个位置。其右面的字符,就是该位置的标识符。比如,

http://www.example.com/index.html#print

就代表网页index.html的print位置。浏览器读取这个URL后,会自动将print位置滚动至可视区域。

为网页位置指定标识符,有两个方法。一是使用锚点,比如<a name=”print”></a>,二是使用id属性,比如<div id=”print” >。

二、HTTP请求不包括#

#是用来指导浏览器动作的,对服务器端完全无用。所以,HTTP请求中不包括#。

比如,访问下面的网址,

http://www.example.com/index.html#print

浏览器实际发出的请求是这样的:

GET /index.html HTTP/1.1

Host: www.example.com

可以看到,只是请求index.html,根本没有”#print”的部分。

三、#后的字符

在第一个#后面出现的任何字符,都会被浏览器解读为位置标识符。这意味着,这些字符都不会被发送到服务器端。

比如,下面URL的原意是指定一个颜色值:

http://www.example.com/?color=#fff

但是,浏览器实际发出的请求是:

GET /?color= HTTP/1.1

Host: www.example.com

可以看到,”#fff”被省略了。只有将#转码为%23,浏览器才会将其作为实义字符处理。也就是说,上面的网址应该被写成:

http://example.com/?color=%23fff

四、改变#不触发网页重载

单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页。

比如,从

http://www.example.com/index.html#location1

改成

http://www.example.com/index.html#location2

浏览器不会重新向服务器请求index.html。

五、改变#会改变浏览器的访问历史

每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置。

这对于ajax应用程序特别有用,可以用不同的#值,表示不同的访问状态,然后向用户给出可以访问某个状态的链接。

值得注意的是,上述规则对IE 6和IE 7不成立,它们不会因为#的改变而增加历史记录。

六、window.location.hash读取#值

window.location.hash这个属性可读可写。读取时,可以用来判断网页状态是否改变;写入时,则会在不重载网页的前提下,创造一条访问历史记录。

七、onhashchange事件

这是一个HTML 5新增的事件,当#值发生变化时,就会触发这个事件。IE8+、Firefox 3.6+、Chrome 5+、Safari 4.0+支持该事件。

它的使用方法有三种:

window.onhashchange = func;

<body onhashchange=”func();”>

window.addEventListener(“hashchange”, func, false);

对于不支持onhashchange的浏览器,可以用setInterval监控location.hash的变化。

八、Google抓取#的机制

默认情况下,Google的网络蜘蛛忽视URL的#部分。

但是,Google还规定,如果你希望Ajax生成的内容被浏览引擎读取,那么URL中可以使用”#!”,Google会自动将其后面的内容转成查询字符串_escaped_fragment_的值。

比如,Google发现新版twitter的URL如下:

http://twitter.com/#!/username

就会自动抓取另一个URL:

http://twitter.com/?_escaped_fragment_=/username

通过这种机制,Google就可以索引动态的Ajax内容。

 

——摘自 阮一峰的网络日志

关于性格内向者的10个误解,献给奋战在一线的程序员

我非常幸运的发现了这本《内向者优势——如何在外向的世界中获得成功》的好书,我感觉就好像是有人专门为我们这个罕见的小群体写了一部百科全书一样,它不仅对我的很多怪癖做了解释,还帮助我从一个崭新且积极的角度重新定义了我的整个人生。

 

毫无疑问,几乎所有认识我的人都会说,“啊哈,你不会到现在才发现你是个性格内向者吧?”,其实这并不是那么简单,问题在于将一些人贴上内向者的标签是一种非常浅显且充满各种常见误解的行为,事实要比这复杂的多(在Carl King讲过之后,就更是如此了)

Laney 的书中有个章节对人的大脑进行了分析,并解释了神经元是如何在内向者和外向者的神经系统中跟随不同的控制通路进行传递。如果这本书基于的科学理论是正确 的,那就证明了内向者是一群对多巴胺过度敏感的群体,太多的外部刺激过量的消耗了它们。相反的,外向者没有足够的多巴胺,他们需要依靠大脑的肾上腺去创造 它们,外向者通常有更短的神经通路,他们的大脑血流量也相对更少,外向者神经系统中的信息大部分都是通过位于前额叶的布罗卡氏区(Broca’s area)传递的,而这里正是我们的大部分思考发生的地方。

不幸的是,根据这本书,只有大约25%的人是内向的,而像我这样极端的就更是少上加少了,这导致了许多的误解,因为社会对我们这类人缺乏足够的了解(我很高兴我能够这样说)

所以下面我列出了一些对内向者的常见的误解(这是我自己的清单,我对其中一些深信不疑):

误解1: 内向者不喜欢说话

并不是这样,内向者不说话只是因为他们觉得没什么好说,他们讨厌闲谈扯淡,如果你让一个内向者讲他感兴趣的事情,他可能连着3天3夜都讲不完。

误解2: 内向者都很害羞

内向者没什么好害羞的,他们也不是害怕陌生人,他们只是需要一个理由去交际,他们不会为了交际而交际,如果你想和一个内向者交流,那就直接聊吧,不用担心礼貌问题。

误解3:内向者都很无礼

内向者通常觉得遵从社交礼仪,拐弯抹角的说话没有一点必要,他们希望每个人都是真实且真诚的,但不幸的是,大多数情况下事情并不是这样,这让内向者感到很大的压力,他们很难融入其中,并为此感到沮丧。

误解4: 内向者不合群

恰好相反,内向者会非常认真的对待他们为数不多的朋友,他们最亲密的朋友或许用一只手就可以统计过来,但如果你有幸被一个性格内向者当做朋友,那你就有了一个终生的盟友,一旦你作为一个人类存在赢得了他们的尊敬,你就入选了。

误解5:内向者不喜欢去公共场合

胡 扯,内向者只是尽可能的避免去公共场所,他们同样也会尽量避免卷入复杂的公共活动,因为他们可以在极短的时间内获取需要的数据和经验,所以,他们喜欢在一 个地方待很久去“得到某样东西”,他们总是准备着回家,调整(Recharging),然后处理一切,实际上,调整绝对是内向者的关键所在。

误解6:内向者总是想要独处

内向者只是喜欢自我思考,他们会想很多,他们会白日做梦,他们喜欢解决问题,攻克难题,但是如果他们找不到什么人来分享他们的发现,他们也能忍受难以想象的孤独。他们希望在同一时间只和一个人保持亲密的感情关系。

误解7:内向者都很古怪

内向者通常都是个人主义者,他们不喜欢随大流,他们喜欢通过特立独行的生活方式来体现自己的价值,他们总是从自我出发,正因如此,他们也常常挑战常规,他们的大部分决定都不会以当前的流行趋势做为参考。

误解8:内向者都是冷漠的书呆子

内向者通常更关注内心世界,他们将更多的精力放到自身的想法和感情上,但这并不代表他们对他们身边的事情漠不关心,只是他们更喜欢通过内心世界来达成自我满足。

误解9:内向者不知道如何放松和享乐

内 向者通常喜欢在家或自然中放松自己,他们不会去那些嘈杂的公共场所,内向者也不会寻求肾上腺素的刺激,如果有太多的空谈和噪音,他们会敬而远之。他们的大 脑对于一种叫做多巴胺的神经递质太过敏感,内向者和外向者拥有完全不同的神经控制通路,关于这一点,你可以深入了解下。

误解10:内向者可以通过“自我修复”变得外向

想 象一个没有内向者的世界,那个世界也就没有什么科学家,音乐家,艺术家,诗人,制片人,医生,数学家,作家和哲学家了,之所以这么说,是因为外向者还是可 以通过学习掌握很多种和内向者进行交流的方式(没错,我故意颠倒了这两个词,读着很别扭?我只是为了让你们看看我们这个社会有多变态),内向者压根不需要 “自我修复”,他们应该因为他们这种天生的性格和为人类做出的贡献而得到应有的尊敬,并且事实上,一项调查(Silverman,1986)显示内向的程 度和IQ成正比。

“你没法避开我们,尝试改变我们只会让你感到失败”,这是我编的,我是一名剧作家。

内向者如果为了去适应外 向者支配的世界而对自己进行否定,结果将会是灾难性的,内向者终将会仇恨自己以及其他所有人。如果你认为你是个内向者,我推荐你研究下这个题目并试着找其 他的性格内向者交换下意见,问题并不完全是内向者应该尝试并“变得正常”,外向者也需要认识和尊敬我们,并且我们也需要学会尊敬我们自己。

原文标题: 10 Myths About Introverts,原文作者:Carl King

从C++到Java,10年技术生涯的几点思考

不知不觉,做程序工作已经10年了,从最初学习C++到Java,从困惑到清晰,感觉真的有不少东西可写,不过总觉得不成体系,大概看了太多八股文章的缘故,被憋得实在难受。所以不管了,想到什么写什么吧。

1、从C++到Java

C++和Java谁快?从算法上讲我认为毫无疑问是汇编〉C++〉Java,不要迷信某些个别评测,单纯的回圈测试什么的,比如JNode的官方网站上有Java写的JVM的性能和SUN的JVM

进行性能比较的结果,JNode中用Java写的JVM竟然能比SUN公司用C++写的JVM还快!编译器完全可以作针对性优化影响测试结果,毫无意义的东西。而且,评测结果不会具备多少实际意义,真正的应用系统的效率是80%取决于整体的设计架构,而非你使用哪种语言。所以讨论汇编、C++、Java谁更快这个问题的人恐怕更多是为了自己的面子考虑,虽然Java当前如日中天,但其总是针对C++的批判性态度却再明显不过,所以Bruce才会有“C++不垃圾,只是Java很傲慢”之说。

C++和Java根本的区别是什么?我认为毫无疑问是内存分配。编程思想和设计模式是活的东西,和语言没有直接关系。Java没有指针,C++写程序也可以只用引用。JVM是Java在

内存管理上真正有别于C++的地方。JVM的好处是显而易见的,跨平台、更智能的内存管理,但能解决所有问题吗,答案是否定的。

Java没有内存泄露吗?当然不是,我认为java的内存泄露往往比C++更加难以排查,因为JVM的缘故,程序员没法直接对内存进行操控,隐患往往藏的更深。我曾经花了大量时间研究JVM的内存机制,虽然也有了不少心得,但直到现在仍然处于迷惑期。循环引用,缓存机制不合理,Spring等常态Bean的属性重复加载都是可能吃内存的元凶。

对于一个单一的,低用户低并发的系统,使用Java是很舒服的,程序员不用去考虑太多事情,照着业务逻辑做设计编代码就行,不用管内存分配,不用管并发和互斥(其实还是要管的),就算万一有内存泄露的隐患,大不了每天重启JVM一下就能解决了。但对于一个可能在多个应用环境中部署的软件产品而言,内存泄露这种问题却绝不能放过。我曾经遇到过在一个环境中运行非常良好,但在另一个环境中却天天出问题的情况,即使每天重启JVM也无济于事。当时怀疑过很多方面,网络、数据库、容器等等。那时还不是很有概念,现在想起来还是后来好好看程序,优化了不少代码,解决了几个内存泄露,这样才最终解决了不稳定的问题。举例来讲,在应用环境A中,服务器性能较好,JVM有2G内存,某个应用存在内存泄露的隐患,每次大约造成2M的内存消耗,这样1000次左右就没有内存可用了,就会造成JVM性能大幅降低。但在应用环境B中,服务器就没那么好的性能了,JVM仅有256M,那么100多次操作就足以导致问题出现。而且,每个应用环境的应用使用率是不一样的,在A中如果每天仅出现10次隐患应用操作,2-3个月都不会暴露问题,而且即使使用内存分析工具,开始阶段也很难查出有无问题,但在B中,如果每天有100次隐患应用操作,只需一天问题就出现了。但实际应用过程中,应用的使用率往往很难精确统计的到,也无法预判,这也是造成问题排查困难的关键因素之一。应用环境的不确定性不单体现在地域上,也体现在时间上,不同时间的相同应用环境也不尽相同。挑选一个应用环境,常态性监测JVM的内存情况是避免这类问题发生的好办法。

结论就是,对于中高端的产品化,多用户,高并发应用,Java和C++一样,不考虑内存是不可能的,毕竟语言最终操纵的还是计算机。

那Java的优势在哪里?我认为其在中低端应用上的门槛更低。对大多数小型信息管理类系统而言,并不需要很严谨并且考虑周到的设计和编码,学习java可以让一个新手很快

 

上路,而C++却没有这种优势,动不动就越界是新手常犯的错误。在一个通常的软件团队里面,水平一定会有高低,而且也不是每个人都能通过学习进入深层次,这是C++难以解决的问题,Java在由于规范性方面的优势更加适合新手使用。

C++就像手动档汽车,Java更像自动档,尽管越来越多人愿意开自动档,可是要想真正跑得快,赛车还得手动挡的。

问题出现总会让人头疼,追根溯源常常也会非常艰苦和漫长,但只要还有办法,就不能放弃,规避问题可以解决阵痛,但永远无法治根。

 

2、关于云计算想到的

毫无疑问云计算的概念被扩大化了,云服务、云存贮,SAAS、IAAS、PAAS,理论和概念早已满天飞。但当我仔细读来,却发现大多还是新瓶装旧酒。虽然说还是有不少实质性内容,但与真正的分布式计算概念还是想去甚远。在网络越来越发达的时代背景下,存贮、软件、外设甚至内存都网络化了,唯一缺少的就是CPU,依靠网络使大量CPU协同工作真的是个很诱人的想法,但也是困难而遥远的事情。也有人认为Cloud Computing是个过度炒作的东西,我觉得有一定道理,如果要我选择,我也会希望把自己的东西放到自己的电脑上,我会更希望在任何地方使用便携设备随时操纵我的电脑,却绝对不是放到一个看不见摸不到的“云端”上头,天天被“云端”盘剥和控制。因此,如果云端仅仅是服务或存贮的集中式管理,它是不值得如此进行炒作的。

其实我觉得我不是一个重组概念进行炒作的反对者,炒作对于技术和社会进步是有一定作用的,但水可载舟、亦可覆舟,将一些本无关系的东西牵强附会的联系在一起进行炒作,只会搅乱理论和学术体系,而理论体系的混乱一定会导致交流上的障碍—–虽然交流变得更多(必然变得更多)更方便了,可是交流的障碍却大幅度增加了,同样的一个名词可以被一百个人给出一百个解释,本来一句话可以说清楚的事情,现在变成了几十句才能说明白。

药厂可以把10几块钱的药重新包装卖200-300块,利润当然是惊人的,可是赚到了钱的老板们却天天打算着转移资产到国外,认为国内没有可持续的发展。这样的人到底是高素质还是低素质呢?

我上大学的时候曾经在医院实习,见过一个食物中毒的病人家属连夜赶了几十里山路,把一堆借来的硬币交给医院做透析;后来工作了,搞图书馆的项目也知道很多地方的人连100块钱的借书证押金都捉襟见肘。那些天天生活在优越环境下的概念重组专家们会为这些人群考虑多少呢?“云端”的概念炒作显现了他们的垄断思想,现在中国的贫富差距基本还是在财产方面,信息方面基本还是对等的,这也是一个农村的孩子经过十几年苦干可以成为大企业家的前提所在。可是“云端”一来,你的一举一动都在我掌控和监视之下,没错,你是方便了,也少花钱了,可是却失去了信息方面的平等地位,于是,屁民将永远是屁民,永远没有咸鱼翻身的机会。

 

3、关于信息爆炸

10年来我也做了很多技术方面的工作了,最初几年看到一项新技术、新概念,肾上腺激素浓度就会大幅度增加,要是不用一下晚上恐怕觉都睡不着。可是后来慢慢地就变得理性多了,技术的选择一定要根据需求来,绝不能为用技术而用技术。很多的新技术、新概念,看几眼就差不多知道来源,也知道优点和缺点了。以前总以为环境得适应程序,后来明白了程序得适应环境。

大型的应用系统,越简单越好,如果做不到简单,宁可拆分为多个系统单独设计。否则,当我面对一大堆连自己都难以看懂的概念和代码,真会有抓狂的感觉。

CSDN是不错的技术社区了,但是依然缺乏体系组织和管理。论坛、知识库,Q&A,这些东西的模式差不多,虽然方便了信息交流,但缺乏信息的组织和管理。比如我希望做一个信息系统,那应该选择什么样的技术?这个问题目前只能靠自己去摸索,慢慢体会,找到真正适合自己的技术方案。Wiki可能是更好的平台,但普及度不够。

其实每一个Questioner或者Answerer都在极力寻求相互之间的共同语言,共同语言和语义的理论体系形成之后,交流才能顺畅。翻翻CSDN的帖子,不乏问东答西的案例。一个交流平台如果能形成一套语言和思维方式,那就是非常成功的了。而这也使得技术选型的模型成为可能,当你想采用一套新技术时,Google一下,各说各话,对的有,错的也有,搜索引擎为何判断不出已定论的东西谁对谁错呢,就是源于语义的复杂性。信息的膨胀速度远没有我们想象中那样快,其中相当一部分是语言语义产生的泡沫,挤掉这些泡沫呢?信息真的有统计数据显示的那么“海量”吗?

统计数据经常是面子工程强有力的支撑者,可扔掉这些浮华,细细究一下统计数据是怎么做出来的?常常就会让人哭笑不得,而且大多是7分真,3分假,或偷换概念,总之目的就是把一棵小草说成一座森林。信息是有欺骗性的,商业运作会大量运用这种特性,换来的除了肾上腺素之外还有人和人之间不信任的感觉。

信息爆炸的时代,交流的作用变成空前重要,但在交流越来越方便的同时,效率也越来越低了。也许几十年后,人类会不堪信息的重负,那时信息规范化和有序化才会真正站上历史的舞台。

 

转自:http://blog.csdn.net/chui88/archive/2011/04/18/6330408.aspx

PHP程序员突破成长瓶颈 – 附学习建议

身边有几个做PHP开发的朋友,因为面试,也接触到不少的PHP工程师,他们常疑虑自己将来在技术上的成长与发展,我常给他们一些建议,希望他们能破突自己,有更好的发展。

PHP工程师面临成长瓶颈

先明确我所指的PHP工程题,是指毕业工作后,主要以PHP进行WEB系统的开发,没有使用其他语言工作过。工作经验大概在3~4年,普通的WEB系统(百万级访问,千成级数据以内或业务逻辑不是特别复杂)开发起基本得心应手,没有什么问题。但他们会这样的物点:

除了PHP不使用其它的语言,可能会点shell 脚本。对PHP的掌握不精(很多PHP手册都没有看完,库除外)知识面比较窄(面对需求,除开使用PHP和mysql ,不知道其它的解决办法)PHP代码以过程为主,认为面向对象的实现太绕,看不懂
这些PHPer 在遇到需要高性能,处理高并发,大量数据的项目或业务逻辑比较复杂(系统需要解决多领域业务的问题)时,缺少思路。不能分析问题的本质,技术判断力比较差,对于问题较快能找出临时的解决办法,但常常在不断临时性的解决办法中,系统和自己一步步走向崩溃。那怎么提高自己呢?怎么可以挑战难度更高的系统?

更高的挑战在那里?

结合我自己的经验,我列出一些具体挑战,让大家先有个感性的认识。

高性能系统的挑战在哪里?

如何选择WEB服务器?要不要使用fast-cgi 模式要不要使用反向代理服务?选择全内存缓存还是硬盘缓存?是否需要负载均衡?是基于应用层,还是网络层? 如何保证高可靠性?你的PHP代码性能如何,使用优化工具后怎么样? 性能瓶颈在那里? 是否需要写成C的扩展?用户访问有什么特点,是读多还是写多?是否需要读写分离?数据如何存储?写入速度和读出速度如何? 数据增涨访问速读如何变化?如何使用缓存? 怎么样考虑失效?数据的一致性怎么保证?
高复杂性系统的挑战在哪里?

能否识别业务所对应的领域?是一个还是多个?能否合理对业务进行抽象,在业务规则变化能以很小的代价实现?数据的一致性、安全性可否保证?是否撑握了面向对象的分析和设计的方法
当我所列出的问题,你都能肯定的回答,我想在技术上你基本已经可能成为架构师了。如何你还不能回答,你需要在以下几个方向加强。

怎么样提高,突破瓶颈

如何你还不能回答,你需要在以下几个方向加强:

分析你所使用的技术其原理和背后运行的机制,这样可以提高你的技术判断力,提高你技术方案选择的正确性;学习大学期间重要的知识, 操作系统原理,数据结构和算法。知道你以前学习都是为了考试,但现在你需要为自己学习,让自己知其所以然。重新开始学习C语言,虽然你在大学已经学过。这不仅是因为你可能需要写PHP扩展,而且还因为,在做C的应用中,有一个时刻关心性能、内存控制、变量生命周期、数据结构和算法的环境。学习面向对象的分析与设计,它是解决复杂问题的有效的方法。学习抽象,它是解决复杂问题的唯一之道。
“这么多的东西怎么学,这得学多久呀” ?

如果你努力的话,有较好的规划,估计需要1~2年的时间,怎么学习的问题,我们后续再谈。

(注:下面是原文作者左文建分享的学习方法)

学习建议

如何有效的学习是一个大问题。 自己有些实践但很零散,不好总结。昨天晚上睡觉前,突然想到了RUP的核心,“以架构为中心,用例驱动,迭代开发”,借用这个思想,关于有效的学习的方法,可以这样来表述:

以原理、模型或机制为中心,任务驱动,迭代学习

有点抽象, 举个例子来说明如何学习。

目的: 学习如何提高处理性能。

可迭代驱动的任务: 通过IP找到所在地域。

这是WEB应用常见的任务,IP数据库是10左右万行的记录。

第一次迭代: 不考虑性能的情况下实现功能(通过PHP来实现)

因为无法直接通过KEY(IP)进行查找地域,所以直接放到数据或通过关联数组这种简单的方法都是不行的。思路还是先把数据进行排序,然后再进行查找

1. 如何通过IP查找? 已序的数据,二分查找是最快的。2. 如何排序?用库函数sort当然 是可以,但是即然是学习,那还是自己实现快速排序吧。
学习目标: 排序算法,查找算法

PHPer 数据结构和算法基础比较差,平时也没有这方面的任务,自己也不学习,因此这方面的知识很缺乏。但是,编程解决的问题,最终都会归结到数据结构和对这种数据结构操作的算法。如果数据结构算法常在心中,那遇到问题就能清晰认识到它内在的结构,解决方法就会自然产生。

第二次迭代:优化数据的加载与排序

如果做到第一步,那基本上还是不可用,因为数据每次都需要的加载和排序,这样太耗时间。 解决的思路是,数据一次加载排序后,放到每个PHP进程能访问到的地方。

放到memcache 这是大家容易想到问题。其实放到共享内存(EA等加速器都支持)中是更快的方式,因为memcache还多了网络操作。 数据是整体放入到共享内存,还是分块放入,如何测试性能? 如何分析瓶颈所在(xdebug)? 在这些问题的驱动下你会学习到

学习目标: 检测、定位、优化PHP性能的方法; PHP实现结构对性能的影响。

第三次迭代: 编写PHP的扩展

性能还是上不去,不得不进入C/C++的世界了,不过从此你将不只是PHPer 而服务端的全能型工程师,当然这对没有做过C/C++的同学挑战是巨大的。 我这里无法再简单来说如何学习C/C++ ,可以参看 《PHP程序员学习C++》

学习目标:C/C++的学习,PHP扩展的编写

怎么确定需要学习的机制和原理呢? 怎么找到驱动学习任务呢?

我对需要学习的东西,都没有什么概念,怎么回答以上的两个问题?

从这个技术的定位来找出需要学习的重点,即它怎么做到(机制)的和它为什么能这样做到 (模型或原理)列出这个技术最常见的应用,做为学习的任务,从简到难进行实践。
假如我需要学习Javascript ,我对于HTML,CSS有点感性认识

首要我了解到,JS 是WEB领域的动态语言,主要解决网页的动态交互的。

那我要学习的要点如下:

JS如何与HTML 进行交互 (机制)JS的动态特性在那里,与其它动态语言有何区别?(语言模型)
如果完全自学,找到需要学习的要点(机制、模型、原理) 设定学习任务的确不是那么容易把握。如果找到一个有经验的人来指导你或加一个学习型的团队,那学习的速度的确会大大提高。

最后,我想说的是: PHP因为简单而使用,但不能因为它的简单而限制我们成长!

作者:左文建