Rise的自留地

记录生活中的点滴,分享编程技术和游戏开发经验。

0%

二十年前读中学的时候,有一位语文老师特别促狭。有一次上作文课,上来说,“今天我要请一位同学来读一读他自己的作文。不过这次和以前不同,我要求连标点符号也要读出来。小K同学,上讲台来读吧!”
小K是班里一位成绩较差的学生,不知道为什么被点名念作文,这通常是优秀学生的荣誉啊。难道小K写了一篇美文?
被点名的可怜的小K慢慢地挪上了讲台,拿着自己的作文本,在手里捏来捏去,半天也没吭气。
老师一把拿过来,“我来念吧!”
只听到老师念了头句,“今天我的作文题目是坚持就是胜利,”说“逗号。”,又念了一句,又是“逗号。”
开始,全体同学没听出什么意思,不过,在老师读到第十个逗号的时候,就开始有人发笑了。待到老师不停的“逗号逗号逗号”时,全面开始笑成一片。小K这篇文章,竟然是从头逗号到尾!直到文章结束,才有一个句号!
我当时也参与了笑话小K,年纪见长,慢慢有些同情小K,觉得那位老师不该这么刻薄,让小K如此丢脸。不过这老兄的作文,未免有些太离谱。
 
以作文而论,“逗到底”的文章大概是最糟糕的文字了。
 
那么,什么是最糟糕的程序员呢?很不幸,如同写文章一样,有“逗到底”的程序员。更不幸的是,小K知道这“逗到底”是不好的文章,很多“逗到底”的程序员还常常自以为高明!
什么样的代码是“逗到底”呢?
 
实现一个功能,不分青红皂白,从头到尾一个函数写到底。你打开代码一看,奥,有一个类,有一个函数,再打开函数,天哪,长到你把鼠标的滚轮摩擦烫了都看不到底。然后他(她)还会告诉你,他(她)的模块很复杂,这是为什么改一个简单的Bug要三天的原因。因为定位到错误点得靠搜索关键字,甚至连搜索都要10秒钟呢!
于是你告诉他(她),你的代码很糟糕。他(她)的回答是:你看,我的代码很整齐啊!
“不行,你得重构你的代码!”
过了几天,告诉你,好了。一看,现在有一个类,两个函数了!原先的大函数被齐腰截成两段,分别放在了原来的函数和一个新函数中。昏倒。
 
“逗到底”的程序员还喜欢非常深的分支。有一次,有位“逗到底”先生向我展示的代码:最上面是一个for循环,里头有个if…else…,每个if从句有for循环,for循环中还有if…else………我看来一会儿,已经完全迷失了,这老兄还向我解释,“你看,排除这个条件后,进入这……”我又晕。用工具一看,竟然有12层之多。我记得大师说过,人类大脑只能立即理解三层嵌套关系,这老兄,我只能佩服啊佩服了。
 
写出“逗到底”代码的就是“逗到底”程序员。其实就是不会程序设计的程序员。我把设计分成产品设计,系统设计和程序设计。产品设计是有产品经理完成的,描述了产品的特性,系统设计描述了系统框架,不如数据库和应用服务器的关系等,程序设计就是对代码结构的设计。我发现很奇怪的一点,声称要成为构架师的很多人特别重视前面两个设计,但很少有人关心程序设计。大部分程序员拿到需要文档后,立马开工,UI画上去,遇到什么逻辑就临时加上。所有的逻辑是平铺直叙,遇到干同样的事情的代码,也抽象成一个函数,而是直接拷贝代码。时间一长,代码就彻底“逗到底”了。谁也不敢改。
 
好了,你,会是“逗到底”的程序员吗?

大D在工作了5年以后,考上了研究生。
 
这是多么令人激动的成就啊!大D虽然并不讨厌做程序员,但总觉得不能如此枯燥地干到三十吧?三十岁还是个程序员,同学面前也没面子。跳槽,多半还得是个程序员,也是前途茫茫!现在好了,上学,谁都不会觉得这是个错!拿个硕士文凭,一辈子对人对己都交代得过去了。而且学的专业是软件工程,将来起码也是做项目管理,比程序员有前途多了!
 
光阴荏苒,一晃大D学业完成,头上也多了顶硕士帽。现在时代变了,硕士也要找工作。不过凭着5年工作经验,大D进了一家知名的外企。唯一的不足,还得从程序员干起。部门经理说了,任谁都得从基层干起,要不然谁服你啊!大D想想也对,也就答应了。大D想,我还能杀不出来吗?
 
大D一直想尽早搞定公司的东西,可是发现东西总是搞不完,不懂不精的东西很多。大D开始怀疑自己。或许是自己弄错了方向?或许这也是工作的性质决定的?
开始的时候,大D总是被安排做不同的东西,不能深入做一件事。等要要深入做一件事的时候,又发现这件事是以前最不拿手,也是最困难的。
 
大D并不是不相信自己的能力,只是觉得自己好像不是现在的工作的最佳人选。对此,大D很沮丧。随着时间的推移,大D发现自己的勇气没有了,尤其是当发现自己经常很累的时候,大D开始怀疑身体能否让自己坚持下去。
 
但是,大D还是不认为自己会搞不好什么东西,当然,大D觉得,这些东西也不象以前想的那么容易。
 
可是,日子还是越来越坏。不知道为什么,大D总是在想许多好像自己改变不了的事情,比如公司的管理方式,软件的开发模式,而不是只考虑做好自己的手头工作,所以常常感到很苦闷。
 
一年以后的有一天,大D终于不能忍受了,他辞职了,同时写了一封信给部门经理,他在信中写到:
……
上研究生使我对技术的关注远不如对管理的关注。我也不知道是对还是错,我慢慢觉得管理上的成功比技术成功能创造更大的价值,或者说只有管理好了,才会有更多的技术创新。我也慢慢觉得自己好像不是个技术上的高手,或者是自己渐渐老了?还是学习少了?我也很疑惑,我参加的培训不少啊,学习一直未停。
我觉得公司用人不当。公司喜欢招人,招高级工程师。可是我发现有些高级工程师来了之后却不能做高级的事情,结果拿着不错的薪水,做初级的事情,浪费了人才、薪水和别人的时间。最后人家也觉得没意思,走人了。这对他本身和公司都是一种浪费,对公司的名声也不好。找合适的人做合适的事就可以了,不要太强求高级,要高手来,只要有挑战性,有足够的薪水,总是有人来的。人家来了,没事做又走了,会带来负面影响的。不过这也不能全怪公司,就像我吧,本来上研究生学的是软件工程,想做项目管理,却被弄来写代码,自己还同意了,自己做的辛苦又不开心,不能怪别人。我就想起来好像韩信学“万人敌”和“一人敌”一样,本来学了排兵布阵,却让去跟人单打独斗,虽然也能打两下,估计还是砍不过人家。结果被人骂,武功不行还打什么仗,却不知道诸葛亮和司马懿是不是都是武林高手。
……”
 
再后来,大D选择了一家国企。

还是一个Simon的故事。

  有一次,Simon和一个程序员G谈为什么要离开上一个公司。

  G说,“我原来在一个小组做struts;后来项目做完了,公司调我到另一个组去。那个组用国内某公司开发的集成开发系统,用工具拖拖拽拽就做完了。我觉得学不到东西,所以就走了。”

  Simon问:“为什么学不到东西?”

  他说:“拖拖拽拽不是把程序员变成傻瓜了吗?”

  Simon问:“Visual C++开发工具也可以用拖拖拽拽完成很多工作,很久以前都得手写的;为什么没有人觉得那是把程序员变成傻瓜呢?”

  他想了想说,那很多Java代码都在组件内,看不到。没有办法学到底层。

  Simon问:“是吗?你觉得你struts掌握得怎么样?”

  他说很熟。

  Simon又问:“那你看过struts的源码吗?”

  他愣住了,说没有。

  于是Simon问G,那你用struts和用那个集成开发工具生成的库有什么不一样?

  G没有办法回答Simon的问题。

  抱着G一样的认识的程序员是很多的。这是个认识自己的问题。我们从各种信息渠道,不知道积累了多少先入为主的谬论而不自知。

  认识自己是最困难的。造物主创造人类的时候,所给予的感知器官:眼、鼻、耳、肤,全部都是一致对外的。这是一个适合认识世界,但不适合认识自己的机制。萦绕在大脑中的,始终是自己的“一厢情愿”。我也和那位G一样,经常随时会自己或被别人发现思想中的自相矛盾,有时羞愧得想要蜷成一团。

  要认识自己,所需要的是勇气和智慧。随着年龄的增长,最大的益处就是能够开始有勇气反省自己,有时用一点自嘲,让自己变得轻松一点。

  希望和大家共勉:慎独而三省其身。

多年前看过一部香港拍摄的武侠片,主演片名是谁是什么,统统忘记了,故事也很老套;但中间有一插曲,一回想起来就忍俊不禁:
 
大恶人为称霸天下,以卑鄙手段杀了名满天下的大侠。大侠临终前告诉少年去找大侠的师叔,学会绝艺,报血海深仇。少年果然不负所托,找到了那个滑稽且高深莫测的老头,从此整天被各种古里古怪的练功方法折磨。
大恶人终于找上门来,这时少年“神功”已有小成!于是拳来脚往,噼里啪嚓嘭,和大恶人打得甚是激烈。毕竟功力尚浅,少年很快处于下风。那个号称天下武学第一的老师叔,明明一出手就应该打倒敌人的,偏偏躲在一边看热闹。
此时,恰好大恶人一个绝招,将少年打得飞将出去,恰好落在老师叔身后。少年叫道:“师叔公救我!”一把就把老师叔推了出去,正落在张牙舞爪追上来的大恶人面前!
大恶人一惊,摆出一个Pose:“来将通名!”
老师叔来不及躲开,只好答道:“天下武功第一某某老头是也!哈哈,你头露破绽!”
大恶人大惊,双手上摆。
老师叔:“你档下可攻!”
大恶人大震,双手上扬下搓,摆出金鸡独立之势!
老师叔:“如此下盘不稳!”
大恶人心中大惧:“我三大绝招,多被识破,我命休已!”
这是少年不干了,大叫:“为何不取其狗命,为大侠报仇!”
老师叔情急之下露了底:“傻小子,我只会说不会打的嘛!”
 
程序员的发展,经常会陷入两个误区。一个是技术至上论,另一个是管理至上论。
技术至上论就是眼里只有各种技术,而忘了工程师的本质是做产品而不是做研究。
管理至上论就是以为个人发展就是为了成为管理者,也忘了产品才是根本。而管理至上论的危害对年轻人是更大的。试想,你去面试,面试官问:你会什么啊?技术至上论者回答:我会A语言B语言C语言……管理至上论回答:我会管A类型人B类型人C类型人……你会要那个?技术至上论者还能干点活,管理至上论者?我招你来管我吗?
技术的积累是需要时间的,而管理的提升往往需要的是顿悟。从一个技术人才转变成管理人才,主要需要的是观念的转变。但管理人才,如果没有过去很好的技术功底是很难去具体做产品的。
可能有人会说,做管理还需要做产品吗?我的反问是:如果你的公司倒闭了,是你(程序员)容易找工作,还是你公司的总经理(那个老头子)容易找工作,特别是不懂技术和产品的的管理总经理?管理岗位一向是一个风险更大的职业。俗话说,人才(总经理)稀缺,位子更稀缺。
有一本书叫做《微软的秘密》,其中讲到微软只雇用既懂技术产品又懂管理的人来做经理。这里提醒刚刚走上管理岗位的年轻人,不要满足于能够管人的感觉,要把更大的精力放在产品开发上。到了60岁,觉得钱赚够了,就可以回家管管孙子孙女去了。:)
我这里有一个checklist,经常用来提醒自己,要Hands-on,hands-on,hands-on!
  1. 每天Review一个系统的设计。Review的时候记住几个关键字:Compatibility,Performance,Fail-over,Load Balance,Redundency,Deployment,Backup/Restor,i18n。
  2. 每天Review一个Bug。
  3. 每天Review一个程序文件。
  4. 每天下载一个开源产品,做一次安装。

最近在学C#,写个保护眼睛的程序(就是过一段时间关下显示器,锁下屏幕之类的)做为练习。以下是关闭显示器的代码,网上好像还没有,在这贴上来,希望对大家有帮助。

与多线程相关的两个常见的需要解决的问题是:临界资源保护和线程间的同步依赖,每一种语言都提供了自己的一套设施(有的语言可能需要借助OS的API)来解决这两个问题,C#提供了更方便灵活的解决方案,首先C#可以允许我们在不同的级别上加锁,也就是说我们可以控制加锁的粒度。其次,C#提供了一套内置的线程安全的容器,方便我们的使用。

一.不同级别(Level)上的同步: 1.object level 同步 对应的class必须从ContextBoundObject继承(同步上下文context,使所有的方法调用能被截获),并且在 class上运用SynchronizationAttribute 。

2.Method level 同步 System.Runtime.CompilerService空间包含的一些属性将影响CLR在运行期间的行为。特性MethodImplAttribute可以用于需要进行同步控制的方法上。

3.code segment level 同步 (1)Monitor类(主要是静态方法) Monitor.Enter(obj)//获得加在对象obj上的锁 ... Monitor.Exit(obj)//释放锁 //上面两句之间的代码相当于lock(obj){...}

Monitor.TryEnter(obj)//该方法立即返回,如果返回值为false,则接下来不需要Monitor.Exit(obj)。

//以下几个方法用于线程间的交互 ==》 解决同步依赖 Monitor.Wait(obj)//等待脉冲消息。释放对象上的锁并阻塞当前线程,以后只有其它线程调用Pulse或PulseAll时才会给它再次获得锁的机会 Monitor.Pulse(obj)//发射脉冲消息( 只有得到锁后才能发射,而且发射不会自动释放锁) Monitor.PulseAll(obj)

注意: (1)Monitor 锁定对象,只能在Enter()和Exit()之间的代码块中调用Wait和Pulse

(2)不能在一个线程中获得锁,而在另一个线程中释放锁。这样会产生锁丢失。 获得锁和释放锁应该在同一个线程中完成。

(3)lock语句 lock(obj) { 需要进行同步的代码 }

(4)ReaderWriterLock类 实现单写多读程序的锁。 AcquireReaderLock()//当没有写程序线程占用锁时,就可获得锁 AcquireWriterLock()//当没有任何读写程序线程占用锁时,才可获得锁 ReleaseReaderLock() ReleaseWriterLock()

(5)ManualResetEvent Set()方法将状态设置为有信号 Reset()将其设置为无信号 WaitOne()将阻塞到其有信号为止,若调用WaitOne的时刻就是有信号的,将不会阻塞

(6)AutoResetEvent 与ManualResetEvent的区别是,AutoResetEvent.WaitOne()会自动改变事件对象的状态,即AutoResetEvent.WaitOne()每执行一次,事件的状态就改变一次。有信号-->无信号;无信号-->有信号

说明: (1)无论是Monitor还是lock、ReaderWriterLock都只对引用类型的对象有效,因为引用类型的对象有一个隐藏的sync#字段,该字段的作用就是作为加锁的标记。 (2)上述的各种设施中,只有Monitor 和ManualResetEvent/AutoResetEvent 能解决线程间的同步依赖问题,而其它的设施主要用于解决临界资源共享。

4.member level同步 (1)Interlocked类(主要是静态方法) 同步一个由许多线程共享的变量。 Decrement(ref int);//使变量减1 Increment(ref int);//使变量加1 //以上两个方法仅针对类int变量 Exchange(ref object, object);

(2)ThreadStaticAttribute 该特性用于修饰静态变量,被该特性修饰的静态变量在每个线程中都有自己的副本。

二.创建线程安全的对象 Hashtable h = Hashtable.Synchronized(new Hashtable()) ; ArrayList等容器也提供类似操作。

以前在同一个进程里,特别钟爱用Sleep(0)来做一些情况下的线程同步。譬如当线城池工作时,主线程使用Sleep(0)来等待线程池里所有的线程都完成运行。当线程池线程非常多的时候,这种方法确实是一种非常有效的节省cpu的方式,因为它节省了在线程里使用内核来进行同步的开销。而且很重要的,它运作的很好,可以说完全在我的控制之内。

Simon是一个软件公司技术总监。有一天,有一位程序员小A提出想要和Simon谈谈。小A工作5年了,程序写得很不错。他进到Simon的办公室,坐下,在Simon的对面。
Simon的桌子有点弧度,于是Simon挪动椅子,和他斜对面。Simon问他有什么事?
“我现在很困惑。我不知道是不是应该转行去做管理。”小A说。
“为什么?”Simon问。
“我看到一些媒体,还有一些认识的Leader都说只有做管理才有前途。”
Simon想了想。小A人很踏实,同时也很聪明,所参加的项目很有挑战性,但他一直做的不错,因此,薪水比同时进公司的员工已经高了20%。
“这样吧,我问你一个问题:现在公司开始执行10%淘汰制。你是一个10个人的组长,因此,你必须淘汰一个。这10个兄弟干得都不错,至少没有吊儿郎当的,跟你的关系都不错。现在的问题是:你准备淘汰那个?”
小A觉得这个问题很难回答。
Simon说:“这样吧,我换一个问题。你喜欢不希望成为作决定的那个人?”
这次小A回答得很快:“不喜欢。”
Simon说:“好,其实你自己已经回答了,你不应该去做管理,因为你根本不喜欢。做一件你不喜欢的事情,你会很不开心。”

和小A一样,其实几乎每个程序员几乎都会面临,或面临过这个问题。
管理是一个很好听好看的词,似乎只要和管理沾了边,就是高薪,荣誉,更广阔的出路。也许对,可我也看到过曾经的技术强人,做了所谓的经理多年后,居然找不到一份满意的工作。因为实际动手能力已经消退了。
所有想要做管理的程序员可以想一想:
管理是什么?管人吗?如果抱着这样的想法去做管理,一定头破血流。现在的时代,没有人愿意被看管的。即使是经理人,也是和人相处,并非凌驾于他人之上。想一想陆纯初,因为一封电邮就被秘书PK下马。
管理有什么用?其实如果大家都好好工作,所有的经理人都是多余的。现代的管理理论是经理人作为协调人,进而是教练。好的管理者应该低调,把荣誉让给干活的人。
管理者也未必比干活的人工资高。存这样想法的人是官本位。我和很多国外公司接触,他们的很多经理告诉我,他手下的高级工程师很多薪水远比他这个boss高,地位也稳固。而经理往往随着公司政局变化而动荡。而高级工程师往往稳得很。
当然,管理者也有很多乐趣,最主要的乐趣在于通过管理的技巧和有效的执行改变团队。但这些往往是隔山打牛的功夫,不是每个人都喜欢这样的工作。

我在包括CSDN内的很多技术论坛看到很多关于是要做管理还是技术的争执,所谓不能做一辈子技术的论调是我不屑于反驳的。但对于走向管理,大部分人是从是不是能挣更多钱(包括所谓前途,爽等),但很少见到有人考虑过是不是喜欢的问题。
实际上程序员们不妨问问自己:
你是希欢智商上的挑战呢,还是情商逆商上的挑战?
如果是前者,请把做技术作为终生追求。
如果是后者,可以试试走向管理。
如果都不喜欢……

过去有一位年轻和尚,一心求道,希望有日成佛。但是,多年苦修参禅,似乎没有进步。
有一天,他打听到深山中有一破旧古寺,住持某老和尚修炼圆通,是得道高僧。
于是,年轻和尚打点行装,跋山涉水,千辛万苦来到老和尚面前。
两人打起了机锋。
年轻和尚:请问老和尚,你得道之前,做什么?
老和尚:砍柴担水做饭。
年轻和尚:那得道之后,又做什么?
老和尚:还是砍柴担水做饭。
年轻和尚于是哂笑:那何谓得道?
老和尚:我得道之前,砍柴时惦念着挑水,挑水时惦念着做饭,做饭时有想着砍柴;得道之后,砍柴即砍柴,担水即担水,做饭即做饭。这就是得道。

翻译成程序员,编一个故事:
过去有一位程序员,一心想追求技术,希望有一天能成为顶级高手。但是,多年学习,似乎没有进步。
有一天,他打听到某高手,到了首都北京,其水平享誉业界,是公认的权威。
于是,程序员打点行装,从牙缝里挤出差旅费,坐火车来到北京,迷了几次路后,咬牙打的找到了高手。
两人开始探讨程序员应该怎么个人发展的问题。
程序员:请问高手,你在名声大震之前,干什么?
高手:在公司写程序。
程序员:成名之后呢?
高手:还是在公司写程序。
程序员于是哂笑:那有什么不一样?
高手:没什么不一样,不过我近来进步,做事情更专心了,不再老是想着写程序发不了财了。这样我就成了高手。

其实,写程序就是写程序。这本身就和前途啊,财富啊不直接关联。只不过时代使然,使它成为刚好是个待遇较好,也是较有机会的行业。因此,年轻一代涌向这个行业,只有一小部分人是兴趣使然。这样,我们所见到的,有毅力,沉得下心的人颇为难得。很多人,坐在电脑屏幕前,要么视为苦差事,要么东张西望,不能定心。如此哪能成功。

每一行都有自己的道,和尚想成佛,俗人想成功。但是不管是谁那行,都只有定心苦修,克服心魔才能有所建树。

也效仿古人写一偈:
一年两年刚入行,三年四年不值讲。
五六七年识门道,八九十年算登堂。

      什么是好的程序员?是不是懂得很多技术细节?还是懂底层编程?还是编程速度比较快?我觉得都不是。对于一些技术细节来说和底层的技术,只要看帮助,查资料就能找到,对于速度快,只要编得多也就熟能生巧了。