程序员怎样提高工作效率的方法,节约时间

问题补充&&
使用代码生成器;Log2Console负责实时显示日志。这些生成器都可以自定义模版,运行单元测试功能。原理很简单。Log4net负责输出日志;有些错误**产生了。开源工具有Nunit,其次是那些使用工具的工匠.
系统上线后排除bug阶段。  3  1。  b)
在开发完一个模块后需要使用**测试来验模块的正确性,国外的产品推荐mygeneration和CodeSmith.
自测阶段,但是不知道客户是如何操作出来了的,而是两个搭配使用的工具.
开发阶段。纯手工敲出来的代码永远是最不值钱的,visualstudio中还有测试工程,少加班。  2。开发阶段的工作大多数就是对**库的增删改查。原理很简单,希望上述工具能够减轻大家的工作量,这样在系统上线后。省掉了大量点鼠标的操作。大家没有没有这样的体会。我相信80%的代码量 都是简单逻辑的。这 时就需要在开发过程中尽可能多的记录日志。所以使用代码生成器生成好代码,比较灵活,我们就可以顺着日志推断出代码的执行顺序。时间和精力都消耗在这等无聊的重复劳动里了,从而找出bug。使用也很简单。  写在最后。  a)
在编码过程中推荐使用单元测试工粳就是使用**测试工具录制我们测试的脚本,粘贴到我们的程序中简单测试即可开发出大多数的代码了,使用单元测试工具和**测试工粳检查是否输出我们需要的结果就可以了。推荐使用工具loadrunner和Selenium,就相当于一个main函数调用我们待测 试的函数而已,登陆系统中要进行好多步骤的操作才能触发我们测试的模块。推荐使用工具log4net和 Log2Console。使用方法。注意这不是两个日志工具。国内的代码 生成器推荐动软代码生成器,我们可以用代码生成器生成大多数的简单逻辑的**库操作,而且 Log2Console可以对不同**的日志分颜色显示,然后反复的使用工具对我们的功能进行验,为了测试一个很小的模块,软件中的复杂逻辑的代码量只占20%。系统上线后客户会提出很多bug有些问题在开发环境中都无法复现,而且还要在界面上录入好多测试**或是准备好多测试**,只要将准备**写在代码中
huanglenzhi &5-09 19:01
•回答
•回答
•回答
•回答
•回答
猜你感兴趣
服务声明: 信息来源于互联网,不保证内容的可靠性、真实性及准确性,仅供参考,版权归原作者所有!Copyright &
Powered by如何提高程序员的生产率(全)
a)&&&&&&&&
大部分开发团队都不把座椅家具视为一个非常重要的问题。拥有宽敞的桌面的环境,可以在桌上放置更多的东西:本子、笔、杯子、书本、打印的资料。更重要的是在和其他人沟通的时候,我们可以一起坐在同一个桌子前面,而不必去找个会议室。宽敞的桌面一定比窄小的桌面更有利于提高程序员的效率,而且费用通常不是想象中的高。
不知道你有没经历过整个开发团队在一个会议室中做集中开发的时间,相信如果经历过的人,都会对这段时间内的工作效率有深刻印象。一个相对封闭的环境能隔绝外部的干扰;所有的沟通都是围绕着工作目标,而不是微博上某个有趣的新闻,能加快团队成员进入高专注状态的速度;团队成员之间可以用语言和目光以及肢体来交流,节省了很多在IM软件上打字的时间。如果让我选择设定一个软件开发的办公区,一个带门的办公室是首选,不管这个门能不能关上。在著名的《人件》中,对于办公空间和安静环境有详细的论述。
对于项目开发中问题的沟通与讨论,是让程序员们脱离那种作为“码农”感觉很有用的一招。而挂在墙上的燃尽图,或者是一叠完成了项目目标,以及一张正在开发的版本目标,又是一种无言的激励。我建议在团队都能方便看到的地方,最好是座位圈的中间,树立一块大大的看板:上面有空间来让团队成员不用把脑袋碰到一起的在纸上讨论;上面可以标识出工作的进度,我打赌这会是项目经理的最爱;同时张贴这版本目标,如同一张张通缉令,而大多数是已经被“捉拿归案”的。
最后一点,可能并不是很多地方会碰到,但是却很致命,就是“空调”。很多办公楼在下班后会关闭中央空调,对于习惯于“过非本地时区”的程序员来说,简直就是噩梦。我还记得曾经周末汗流浃背的趴在电脑前工作的烦躁感,要直到深夜,才会稍微感觉舒服些。一定要7x24的空调,否则办公区机房也会出问题。
所以的这一切,可能对于开发进度的推动,并非属于“高科技”的行列,但是所谓成本也不高,就算抱着试一试的态度,也绝对值得实践。黑网吧一样的工作环境,并不代表艰苦奋斗。
如果按程序员的工资,来算一算有多少时间是在等待工作电脑上做出的“响应”的话,一年之后,这些被浪费的金钱足够再买十台电脑。更重要的是,为了打发等待电脑的时间,程序员们会跑去浏览网页、聊天、吃东西……而专注的精力就这样被消耗掉了。为了恢复进入到专注的状态,程序员需要10倍于刚才浪费掉的时间。在这些神不守舍的时间内,如果还在写代码,更加是增加了留下大堆BUG的风险。买市场上最好的PC——对比你在项目延迟和BUG中消耗的金钱来说,简直是九牛一毛。而且这些固定资产投资,本身也是公司的一部分,并不是“白白消费掉”了的。购置牛逼的PC,看起来需要很多资金,但是这几乎是最便宜的提升程序员开发效率的东西。
使用两个以上的显示器,能明显减少使用者在窗口切换中的时间,更重要的是能快速恢复注意力。在开发过程中,注意力往往需要集中在某一个窗口,而同时兼顾其他窗口。而在诸多窗口中翻来翻去,是最容易分散注意力的事情。现在PC的集成显卡往往有2个视频端口输出,如果还有多一个外置显卡,则有4个端口。善加利用这些好的措施吧。当然也有一些人喜欢用一个比较巨大的显示器,其实也是同样的道理,他们会让显示器上同时显示不同的内容。
防止木马和病毒,特别是对非技术人员电脑的服务,是非常重要的工作,我不止一次的碰到过某些非技术岗位的电脑出现严重问题而影响整个开发进度。
c)&&&&&&&&
几乎在每家公司,我都能见到爬满地面的网线,还有尘封在某个角落的8口交换机。“上网很慢”的呼声常常从员工的口中听到。等待网络响应和等待电脑响应的意义是一样的,都是在浪费公司的金钱。提供足够的局域网带宽和外网带宽,是必须要做的事情。一个20人的开发团队,应该在20M以上的互联网带宽环境下工作,局域网则毫无疑问的应该用能买到的最快的配置,现在已经是千兆网了。而且应该配备优质的无线网络,能有效降低网线爬满办公室地面的面积。
网络的管理也是一个非常重要的部分,用技术手段限制每个人的带宽占用是必要的,设置一个文件服务器专门存放那些被反复下载的大型文件,如IDE,是一个很好的做法。IT标准化是一门很专业的学问,能在这个方面去努力,一定也是物有所值的。
如果一个银行没有自己的保险库,而是把钱都放在各个职员脚下的小铁皮盒子里,这种情况当然是匪夷所思的。但是很多公司的开发团队,却把开发的成果——代码、图片、文件放在每个人的PC里面,只在必要的时候才集合到一起,然后放到老大的PC里面。每个团队都应该有自己精心维护的“保险库”,就是局域网中的服务器,应该有专人管理和维护这些服务器,并且设置自动备份和紧急恢复的机制。每个开发人员都必须要有,“把完成的工作放到服务器上”才算完成的观念。我承认很多美术设计人员很不习惯,但是在承受过多次文件丢失的教训后,不管有多大的困难,都应该养成这个习惯。
e)&&&&&&&&
总结:硬件是最直接显示资金支出的东西,节省这些钱似乎是为公司着想,但是我觉得适当“挥霍”,也是一种对公司的负责。因为这些投入是最便宜的,能提高程序员开发效率——可谓世纪难题,的方法。
a)&&&&&&&&
开发工具:
木匠们给我最深刻的印象是,他们只要一开工,就立刻会搭起一张简易的工作台,虽然看起来很粗糙,但是坚固而平整。程序员是具有丰富电脑使用经验的人员,但是并非每个人都意识到应该先给自己“搭个工作台”。
1.&&&&&&&&
“这个文件到底在哪里呢?”我相信每个人都碰到过这个问题。因此有些人的桌面铺满了密密麻麻的图标。节省找文件的时间,就是提高开发效率。对于WIN7来说,可以自定义“库”是个很好的功能。而TortoiseSVN也会自动建立“SVN库”。为你开发项目定义好一个“库”,能大量节省翻文件的时间。把你每天都用的程序,固定到任务栏中,删掉所以其他的图标,因为很多软件都喜欢在你安装它之后,就赖在任务栏上不走。
桌面是我最常用的“临时”目录,我甚至把下载目录设置为桌面。但是所有的临时文件,一旦我决定不会经常打开,我就会毫不犹豫的删掉,或者挪到别的目录上。桌面上我更倾向去放那些我近期工作就要处理的文件,以及那些经常要打开的文件的快捷方式。这样每次开机都会提醒我还有些什么工作需要做。每隔一段时间我就会清理我的桌面,对于一些很少使用的快捷方式我会直接删掉,然后把那些甚少打开的文件去归类的放到文件目录中去。你可以看一眼我的桌面,就知道我日常的工作。
如果你通过命令行去使用LINUX这种系统,输入长长的路径,就算有TAB的自动补全,也是非常繁琐的事情。建立一些软连接(ln
&s),或者写一些shell脚本,都能让你从这些烦人的键盘敲打中解脱出来。
有另外一些人会比较爱好使用搜索功能,而且现在WIN7的搜索也很好很强大。使用搜索也确实能快速找到你要的东西。但是我不认为因为有这个功能,就应该把东西随便乱丢,因为总有一天你需要归类整理、备份这些文件。在没有“关键词”的情况下,你只能依赖以前的目录结构了。
也许精心安排文件路径、放置快捷方式、设定软连接和编写只是节省了十来个敲键的简单脚本,会被看成是小题大做。但是我确实在不同做法的程序员之间找到过明显的效率差异。一个有趣的现象是,越是经验少的程序员,他的桌面越显混乱。
2.&&&&&&&&
设置好你的PATH变量,这是第一步。
LINUX下大多数的程序,都可用管道串接组合起来实现一个更复杂的功能。这给与了使用者机器丰富的灵活些,来创造自己的工具。这些计算机界的先知们创造了这套机制,如果我们不去享用,实在是罪过。我会把常用登录命令变成一个脚本,减少去敲别扭的IP地址;我会把登录数据库的命令也写成一个脚本,这样不用去记忆复杂的参数;我还会去把同步文件的命令做成脚本……把所有常用的,超过5个字的命令都变成脚本,就算这个脚本只有短短的一行或几行,都会大大降低工作强度。虽然GUI看起来漂亮,很吸引人,但是手指可以不碰鼠标,而一直在键盘上工作会高效许多。
WINDOWS下的BAT也是脚本,但是并不好用,因为WINDOWS本身是GUI类型的。但是不妨碍使用宏这种工具。
尽量多的编写一些自己用的脚本,你会发现很容易记住并且依赖他们。
3.&&&&&&&&
到底程序员是否需要IDE,这个问题其实很值得商讨。我曾经直接用EditPlus来写过数千行PHP代码。也曾直接用VI来做JAVA的开发工具。这些编辑器打开的速度能使我快速的投入到工作中去。而Eclipse和VC这种慢吞吞的IDE,却浪费了我大量的时间和注意力。我更倾向于在项目初期的研究阶段,尽量少用IDE去写代码。而在所有的技术风险都解决之后,再启动IDE作为正式项目的开发工具。
IDE对比普通的文本编辑器来说,效率提高的其实是各种快捷键。如果你用Eclipse,一定要懂得用Ctrl+Shift+r来打开文件,也一定要懂得用Ctrl+o来定位代码,按着Ctrl来点击代码,以及使用Atl+/都是很好用的快捷键,有了这些功能,我再也不会担心因为拼写错误造成的BUG,而且变量方法的名字长一点也不是问题,因为电脑会帮我自动输入。而多重剪贴板也几乎是必备的工具。另外,IDE通常都有带一些自动机制,如存盘就自动编译,可以让你快速修正编译错误,提高开发速度。还有如Aptana写PHP和JS,可以自动上传到服务器。这些都是很实用的功能。
断点单步调试也是IDE一个非常重要的功能,有很多程序员从来没有用过断点调试这个功能,因为根本就没在开发PC上搭建过运行环境。这个是一定要花功夫去弄好的,否则反复在测试环境上修改代码、增加日志、尝试运行的繁琐步骤会把人逼疯。
有些IDE还可以把SVN结合起来,那就更方便了,绝对是值得推荐的用法。还有的IDE可以和单元测试组件结合。每次编译都自动运行单元测试,这个也是很值得推广的实践。
最后说说一个很重要的问题,就是开发团队中,最好所有人都用同样一个版本的IDE,然后共享所有的配置设定,这些配置设定最好直接作为源代码的一部分放到SVN上管理。如我喜欢把Eclipse的整个workspace放到SVN路径上,这样所有项目的.project文件都可以一起管理,我如果有一天硬盘挂了,我可以直接从SVN上checkout整个workspace,瞬间重建我的工作环境。无论何时,无论在谁的机器上,都能轻易重建开发环境,对于团队合作解决问题有非常重要的意义。这种做法也能推广IDE的一些使用技巧。虽然程序员喜欢彰显个性,但是对于取消一点个性而带来的好处来看,是绝对值得的!——我一直对于设定一个“养眼”的底色有强烈的爱好,这个简单的设定也常得很多同事的支持,用这种方法可以让所有人的获得这个好处。
4.&&&&&&&&
一个好用的文本编辑器,是程序员的瑞士军刀,用来处理一切临时的、复杂繁琐的工作。每个程序员都应该有一个优秀的文本编辑器,它要有飞快的打开速度,可以同时打开多个文件,有优秀的查找替换功能,对于XML\SQL和大多数的脚本、编程语言都有语法上色功能,而且可以存成不同编码的文本。我认为LINUX上的VI是最好的,现在WINDOWS上也有了。另外古老的UltraEdit可以编辑二进制内容,EditPlus拥有很好的语法上色,Notepad++各方面都挺不错,而且是免费的。这些都是值得考虑的。特别是文本内码转换功能,LIUNX和DOS的换行,都是很常用的需求。(在LINUX上有方便的dos2unix/unix2dos和iconv)
除了安装一个这种软件,还需要把所有可能编辑的文件类型的默认打开程序都设置成它。这个设置工作会大大减轻日后工作中的操作负担!我甚至建议公司的IT人员应该对程序员的PC做标准安装的时候,就设置好这个功能。
5.&&&&&&&&
数据表格是程序员接触到的主要业务数据格式,大部分非技术人员都会把“数据”类型的文件用excel来存储。而Excel强大的筛选、统计图功能也是程序员乐意输出给其他工种同事的原因。因此程序员的PC上的OFFICE套件至少应该有一个Excel,或者免费版本的替代品如WPS或者OpenOffice.org。
而且程序员需要掌握直接用API来生成和解析EXCEL的技能,这个技能会让跨工种沟通节省很多时间。特别是节省各种因为“格式错误”导致的问题。我就曾碰到过一个XML数据文件因为一个小小的语法问题,困住产品人员一整天的事情。如果你确实不想用微软的这种封闭技术,那么用更建议的CSV格式也是很好的,因为你同样可以用excel来打开,只是不能拥有合并单元格、字体、颜色这些外观性功能。
6.&&&&&&&&
程序员大部分的图应该用笔画在纸上,或者白板上。但是更重要的是,程序员应该多画图来记录自己的思路。这种思路最后的定稿,最好是以电子文档来记录。我使用过数款画图软件,如Dia,OpenOffice.org,甚至是WINDOWS的画笔,Flash
CS,但是最好用的还是微软的VISIO,特别是画UML图。虽然这个软件价值不菲,但绝对值得使用。千行文字不如一个图来的清楚。很遗憾我还没找到开源的或者免费的软件能媲美VISIO的。
7.&&&&&&&&
MindMenager
思维导图软件出现的时间并不长。这种软件强迫你按树状来梳理你的思路。对于有条理性自觉的人,其实这个工具的意义不是太大,只是一个快速画“树”的软件。但是如果对于问题思考还未能很有条理的时候,这种软件确实能帮助人理清思路。通常这种导图文件并不能成为真正的文档产出物,更更像是一种草稿。但是还是建议程序员尝试使用它。除了收费的MindMenager以外,有多款开源的思维导图软件可选,功能都不错。为了文件格式的兼容,团队内应该确定用其中一个。开源的FreeMind是个不错的选择
8.&&&&&&&&
开发服务器
a)&&&&&&&&
使用程序员的PC
似乎服务器程序开发都有一个传统,就是使用专用的开发服务器,然后由程序员的PC上传并且远程控制这个服务器,来做开发和调试。但是在我开发JAVA服务的实践中,让客户端直接连接到自己的PC上,利用IDE的调试器,确是能大大提高联调的速度。根据很粗略的估计,使用直连PC联调会比基于服务器联调节省最少70%的时间。因为漫长的看日志(或者是使用GDB,有很多初级程序员都不太能熟练的使用命令行的调试工具)、改代码、上传、编译、然后召唤客户端程序员重新发起请求……这些事情占了很多时间和宝贵的注意力。如果客户端和服务端都以IDE方式运行在同一个PC上,你可以两边都做断点单步调试,一切问题都变得异常简单。
得益于JAVA的跨平台特性,在程序员PC上调试过的程序,几乎不会在真正的服务器上有太多的BUG。实际上如PHP、PYTHON这些脚本语言,也是能做到类似的效果。而很多C++程序员也习惯用宏定义来让LINUX上的程序在VC上编译调试。但是始终不如JAVA那么方便。
在性能调整的工作中,如果让压测实际运行在程序员PC上,可以调用很多漂亮的GUI性能分析工具,如JConsol。这也能性能改进工作有个很好的环境。
尽量在程序员的PC上搭建完整的开发调试环境,少依赖复杂的“开发服务器”环境,会让开发速度有很大的提升。
使用虚拟机
现在的PC性能普遍很高,而且还有专门为了支持虚拟机的硬件支持,从性能上来看,是支持大量使用虚拟机的可能性的。
在WINDOWS上开发LINUX程序,如果用虚拟机装一个LINUX,然后以GNOME界面的IDE开发,会是一种很便利的工具。因为和服务器同样是LINUX,所以大部分的程序开发之后可以直接放到服务器上运行,都不会有什么不同。而且LINUX本身有很多好用的功能,如利用SSHD的远程文件夹,可以更好的和别的LINUX服务器做互动操作。同时一些WINDOWS的程序也可以在虚拟机以外来运行。特别是现在还支持剪贴板和文件分区共享,用起来就更方便了。
作为开发服务器,实际上负载通常很低,所以在一个物理服务器上安装多套虚拟机,可以让每个项目都有自己完整的一套环境,是节省成本和管理费用的好方法。甚至很多工具服务器都可以是虚拟机,除了SVN。
c)&&&&&&&&
文件同步技巧
多个机器之间的文件同步,是很常见的一种需求。一般LINUX服务器采用sshd和scp功能来拷贝文件,这个命令行工具使用起来比较方便,缺点是必须要手工输入密码。作为脚本就比较麻烦。所以一般有两种方案,一种是用expect这个
shell来写脚本,模拟输入密码。另外一个就是使用rsync,这个软件可以对sshd服务器直接去同步文件,也是很方便的。可以用推或者拉两种不同的方案,更重要的是rsync可以指定密码文件,成为脚本的好帮手。
另外一个就是用samba,直接从WINDOWS的共享目录功能去拷贝文件,虽然也算好用,但是写bat去运行总觉得不够强大。也有用SVN来传递文件的,但是这并不符合SVN的“提交”含义,是一种不好的做法。最后还有一些通过装一个WEB服务器,然后从另外一边用wget来下载,这种对于定时自动运行的程序来说不失为一种方案,但是缺点是不够灵活,只能限定是下载,而且限定了路径。
总结来说,rsync和httpd+wget是毕竟好的同步文件方法。
反思必要性
如同本节第一点所说,很多时候在程序员自己的PC上处理开发工作,是效率最高的,所以是否一定要有“开发服务器”是一个值得思考的问题。在具体的实践中,那些开发工作通常在PC上完成的团队,其“开发服务器”往往是一个测试服务器,用来对最终联通,展示临时效果,内部QA之用。反而真正很少人在上面调试。可能取消“开发服务器”是最好的,但是这个需要更多的实践来证明。
9.&&&&&&&&
构建服务环境
a)&&&&&&&&
对于C/C++类项目来说,构建是一门相当复杂的工作;而JAVA项目则相对简单一些,只是需要一些打包的脚本,用ANT完全可以搞定。不管如何,一个可以自动从SVN上下载资源,然后在一个空白环境下生成“可安装包”的脚本,是绝对必要的。而且应该是能全自动处理,每天都自动编译一个安装包出来。这个是现在最流行的所谓“持续集成”的基础。
这里面还有一个小技巧就是关于“版本号”,一般来说构建脚本应该支持以命令行参数方式输入版本号的功能。而版本号则应该能在构建过程中,编译到项目代码中去,这样在运行这些代码的时候,就可以编写一些输出“版本号”的语句,以便在测试过程中确定软件的版本。C/C++项目可以用环境变量配合宏定义来处理。JAVA和其他一些项目,则需要写一个version文件。
构建服务器
构建服务器必须是单独的,空白的环境,建议使用虚拟机。构建服务器本身应该和目标部署服务器的系统采用尽可能一致,特别是对于C/C++项目来说,内核版本,64还是32位的系统,都至关重要。如果编译过程需要一些额外的库和工具,首选从SVN上下载,作为项目的一部分,如果实在无法做到,则需要有清晰的“服务器构建软件环境”的自己的安装包SVN和安装配置说明文档(同样放在SVN上)。我建议构建服务器、测试服务器、开发服务器、运营服务器都基于同一个系统环境的设定去安装。如都安装同样版本的GCC或者JDK,安装同样版本的PYTHON和apache等等。
测试服务器(内测)
安排一台服务器放在局域网,随时在上面部署最新的代码,是一个很有必要的布置。因为产品、美术或者其他一些非技术人员,可能需要依赖最新的代码对产品进行另外一种“开发”——添加数据内容。有一个不受程序员频繁修改调试的服务器,对于他们的工作效率是很有益处的。同样程序员也不用受制于别的工种进行开发。
为了利用好测试服务器的功能,有一个非常重要的工作,就是让代码能够自动的部署到测试服务器上。如果还是由程序员去部署,这个额外的体力劳动会消耗不必要的程序员的时间。而编写自动部署的脚本和预先设定环境,虽然一开始会消耗不少时间,但是这些自动部署的工具,同样可以用于别的测试环境甚至是正式运营网络上的服务器,是一个一箭双雕的好事情。
对于美术、产品或者别的非技术人员,添加的数据往往也需要有自动部署的工具,而且因为通常他们产生的文件比较大,每次的全体打包然后覆盖,可能会非常没效率。比如美术资源一共有10G,但是你只需要更新其中的2M的文件。这个时候就要设计好“增量”部署的脚本,或者你可以看成是“补丁”型部署包。用rsync可以只拷贝有变更的文件,而tar也可以指定打包的文件,或者写一个精巧的Python程序来处理,也可以尝试用make和ANT工具来实现。虽然这个事情不是太容易做的完美,但是绝对是物有所值。
体验网环境(外测)
很多时候,网络环境会暴露出很多意想不到的问题,如网速变慢,有些交互会变得奇怪。在不同的服务器上,部署和配置可能会出现错误。而且对于测试人员来说,一个和真实运营环境高度相似的测试环境是非常重要的。最好还能让不同的测试人员从各种不同的接入网络(客户端网络)来测试。因此一个具有类似于正式运营网络的环境,显得尤其有价值。
对于发布和部署来说,也是一个真实考验自动部署和发布工具的最好测试环境。体验网的环境,实际上应该拒绝开发人员直接访问,而真正的给运维人员一个实战的环境,看是否有一些遗漏的问题。只有经过了体验网的测试,产品才真正能部署到外网运营环境中。
一个隔绝开发人员的体验网环境,除了能提供更实际的测试条件外,还能提供很好的管理区域分界:开发和运营。通过这个环境,能区分出哪些问题是开发引入的,哪些是运维引入的。
有些有条件的团队还可以要求一些外界的人士参与对体验网上产品的测试,这样更加能提高测试的细致程度。不过能提供这种支持资源的公司并不多,因为用户也是需要资源去换取才会来测试的。如果有一定用户来,还可以录制他们的测试行为,然后为压力测试提供原始数据。
压力测试是一种比较讲究技术的开发工作。除了自己模拟一些情况外,录制用户的行为然后按登录会话并发请求,是一个很使用的压力测试策略。为了避免压力测试占用开发网络和服务器太多的资源。一般会专门配置发起压力和承受压力的服务器,然后让他们接到独自的一个交换机上。
单元测试工具
单元测试的概念是最原始的工程概念之一。早在单元测试工具出现之前,就有人提倡为每个类都写一个main()函数,里面专门放一些自己编写的测试代码。现代的xUint工具已经普及多重语言,如JUnit,
ASUnit等等。不断追求自动化和边界的测试工具,应该是每个程序员的目标。完善的测试能解放程序员的巨大心理压力——改了很多代码后,会不会有BUG?用程序来自动检查,是最好不过的了。实际上现代编译器都提供很多规则,这些规则也是一种静态检查,好的代码能通过静态检查后,大大减少BUG。单元测试则类似于这种检查,但是是动态的,所以需要程序员自己用测试代码去定义“规则”。在编写准备去单元测试的代码的时候,会让这些代码变得结构更良好,因为第一个使用这些代码的客户程序员就是自己。
单元测试对于互联网应用来说,一般会有一个困难,就是需要大量的“脚手架”,比如为了测试数据库操作,必须要有一段代码“重置”数据库的状态;为了测试网络打包解包,则需要用一个程序向某个网络端口发数据。准备这些测试工具代码的时间,往往会比较长,需要有足够的耐心去做,但是一旦做好了,往往能让开发风险大大降低。
合作工具:
有一门专门的知识叫:软件配置管理。其实讲的大多数就是如何利用合作工具来提高开发效率的。一般来说,编译型语言的软件配置管理会比较复杂,而解释性语言的软件配置管理则简单的多。我认为合作之中沟通、交换是2个主要主题。沟通方面面谈是最有效的手段,而交换则应该多利用工具。
&&&&&&&&&&&&&&&&&&&&&&&&
i.&&&&&&&&&&&&&
SVN是优秀而免费的版本管理工具。采用检出-提交-合并的模式处理文件,同事对于建立分支成本极低。所以应该合作工具中最重要的部分。
SVN的使用书籍汗牛充栋,我认为最需要关注的2点:一是对于非文本文件的控制,因为SVN不会自动合并,所以应该多用“锁”的功能,来提醒别的用户不要覆盖了自己的修改。二是善用分支的功能,标准的做法有trunk/branch/tag的这种分支方案。
服务端因为部署成本比较低,所以倾向于直接在trunk上开发,有远期或者可能冲突的目标才开branch,而测试也直接在trunk上做测试。客户端因为部署成本高,一般不愿意代码和资源在开发工程中打包发布和测试,所以倾向开一个dev-branch专门用于开发,而trunk专门用于发布测速。我个人的经验是,如果程序结构足够良好,能在trunk上做到直接开发发布是最好的,因为合并操作毕竟是多一个步骤。而要做到这一点,就必须对功能按模块修改做到很好,特别是客户端代码,因为涉及发布包的大小问题,要做到还没开发完的模块就不打包生成安装包,是需要一定的设计的。而关于branch,我的看法是应该根据功能点来生成,很多时候大家喜欢根据版本目标来做branch,但是根据经验,版本延期和版本内容修改经常发生,这个时候就被迫做一些分支合并和提前都是很麻烦的事情。SVN新建分支异常低成本,所以tag分支可以多做一些,每日一个虽然夸张了点,但是每周一个肯定是问题不大的。对于测试人员来说,能有一个固定版本的源代码来做测试,会减少很多不必要的BUG的检测。
下面说说SVN不应该有的用法:第一个是拿SVN当文件传输工具,这样会让版本库中带有大量的无用的日志,而且SVN并非一个专用的文件同步工具,会产生一些额外的问题,比如生成大量占用空间的.svn目录。另外每次提交都应该具备自我包含的一个功能特性,否则对于做基线或者做分支会很混乱;第二个是SVN中存放目录结构经常会变化的文件,有些如日志文件,因为会不断生成目录,所以会导致.svn目录变多,最后搞得很混乱;
SVN除了基本的功能,还有很多可扩展的功能,也是很优秀的。如你可以在提交的注释中按照某些规则来写文字,触发别的工具。如JIRA就可以设定在注释中写“#bug-id”来自动更新对应bug的状态。SVN因为拥有很好用的触发器,所以做这些自动化功能轻而易举。如果针对代码提交有一些管理工作,强烈建议整合到SVN的工具里面去,如BUG的跟踪、工作量统计、通知同组同事修改内容等等。
&&&&&&&&&&&&&&&&&&&&&&
ii.&&&&&&&&&&&&&
wiki/知识库/IntraBBS
写程序的同时会有大量的文档,如何管理这些文档,是一个重要课题。我认为文档主要分为几类:一、API使用手册;二、架构设计文档;三、经验知识的积累。
关于“API使用手册”这类文档,有javadoc这类直接嵌入在源代码中的文档规范,然后有天然工具可以自动导出。我认为这类文档在自动构建的时候同时自动输出,然后跟随发布包发布是最好的。使用者可以跟随同版本软件一起获取。
关于“架构设计文档”这类,最大的问题是版本更新,因为往往进入开发期之后就少有人再去更新,导致后来需要用的时候,已经有大量不同,而这个时候往往是有人离职需要交接的紧要关头。这类文档从开发角度,放在SVN还是放到内部WIKI上其实都是好的,但是关键是怎样维护。个人意见如果团队较小,直接用SVN即可。如果团队成员超过50人,文档可以由多个人一起去写,放到WIKI上能彰显大家的努力,也方便大家查阅。
内部BBS很多时候最后变成灌水圣地,对于开发效率的推动其实不大,不过作为一个“软福利”,有些时候也有一点用,总体来说我不太认可这种东西的价值。
&&&&&&&&&&&&&&&&&&&&&
iii.&&&&&&&&&&&&&
IM(QQ,RTX...)/E-MAIL座机/sms
关掉IM!关掉E-MAIL!电脑上的即时通讯工具被某些人认为是“必备”的工具,而我则认为邮件才真正是工作用的工具。考虑到程序员的注意力很容易被这些突然闯入的信息所干扰,我更倾向于直接关掉IM软件。电子邮件也只在固定时候收取,如中午和下班前。很多人对IM和邮件反应很快,很多时候是因为他们根本没在认真干活,或者工作并不饱和。座机和短信是一般办公的必备工具,座机可以省了跑来跑去的沟通,但我认为当面沟通还是比座机要好。我理想的办公室应该是通道宽敞,每4-6个座位中间都可以有个小型讨论区,有白班和多于的几把椅子和一张小桌子。
短信我认为还是很好用的一种工具,特别是某些需要记住的信息,比如日程提醒、电话号码、或者一些IP地址之类的东西。用来作为每天的业绩提醒,发给团队中所有人,也是很好的。另外用来作为自动报警消息,是保证不在IM和邮件叨扰的情况下最关键的实时通知工具。设置一个企业自己的短信网关,是很有必要也很有价值的。
&&&&&&&&&&&&&&&&&&&&
iv.&&&&&&&&&&&&&
公共文件服务器
公共文件服务器可以是WINDOWS也可以是LINUX+SAMBA。我认为这个服务器是SVN的一种补充。主要用来存放两种文件:1)开发工具和各种服务器软件。这些软件应该是标准化环境的一部分,所以应该共享使用。2)每日构建的发布包以及各种版本的发布包。发布包本身在测试工作中是最基本的需求,所以应该有一个集中的地方存放。我建议同时这个服务器也具备HTTP下载功能,这样很多LINUX脚本也可以自动去抓数据了。
&&&&&&&&&&&&&&&&&&&&&&
v.&&&&&&&&&&&&&
持续集成服务hudson
持续集成是现代软件开发的重要目标。如果没有自动化的持续集成工具,软件的开发和测试将会效率非常低下。Hudson是一个很好的持续集成工具,可以直接从SVN下载代码,执行脚本然后运行。本身是JAVA的程序可以同时处理WINDOWS和LINUX上的构建。
持续集成的基础是SVN版本管理的标准化;然后是拥有自动化的构建脚本;最后是拥有自动的打包和部署脚本。持续集成系统只是把这些工作串起来的一个工具。
不管持续集成是多么的繁琐的工作,但是这些一定会物有所值。
&&&&&&&&&&&&&&&&&&&&
vi.&&&&&&&&&&&&&
开发者微博
有些开发方微博实际上是市场宣传软文,我暂时不讨论这个。有一种实践是把SVN的注释自动提交到WIKI上,然后大家用RSS订阅。其实这个就是一种SVN的注释自动生成的微博。这种方法用来自动沟通代码修改,其实是很自动化和看起来可行的。实际上大部分人都只关系一部分代码,只有管理者会比较关心大部分内容。所以用发送电子邮件可能比上微博要好。也有一些关闭了IM软件的团队用内部微博来公布广播消息,也比较受欢迎。不过我个人不赞成为了这单需求去搭个内部微博,还是自动邮件好了。
&&&&&&&&&&&&&&&&&&&
vii.&&&&&&&&&&&&&
远程桌面服务器、跳板机
很多时候为了提供团队成员可以在办公室外环境工作,都需要架设一个“跳板机“供直接远程桌面到自己的办公机上干活。我承认这个做法确实能解决一些临时事故修理的问题,但是实际上安全隐患很大,如果跳板机被攻破,整个公司的代码可能就被拷贝走!
架设远程桌面服务器、跳板机,一定要做到非常高的安全级别,起码都要不被网络上扫描掉。否则就不如不做。
c)&&&&&&&&
管理工具:
&&&&&&&&&&&&&&&&&&&&&&&&
i.&&&&&&&&&&&&&
缺陷跟踪管理工具JIRA
其实这种工具也算一种沟通工具,有时候可以代替Project这类软件,据说互联网上很多开源项目都是用JIRA来做特性和缺陷管理。使用这类工具管理者比开发人员要积极,因为这个工具更多的是“任务分派”和“任务统计”的功能。而开发人员则需要不停的去查看自己的任务,然后做完之后还要手动上去提交或者写意见。写注释这种事情有时候是比较蛋疼的,很可能没有人会看,原因是写注释的人很少写的很清楚。所以使用这种工具,我认为最重要的是要做好自动化插件,如SVN直接用注释驱动JIRA去改进任务。
如果你同时在使用EXCEL或者PROJECT和JIRA同时来管理工作进度,这里就会有一个很大的风险:JIRA上的问题和缺陷会难以纳入到你的工作总体任务列表中,因为这些缺陷可能测试人员在不断的添加。
使用缺陷管理工具的最好实践是,全部任务都用这个系统来管理;如果不能的话,就不要把BUG以外的任务纳入这个系统;如果还是不能的话,就要做好人工的“分级”制度,或者为每个任务都严格加上一个“版本”的属性,用来划分出哪些是应该在现在就要完成。
&&&&&&&&&&&&&&&&&&&&&&
ii.&&&&&&&&&&&&&
项目进度管理工具Project(Server)/
Project是个好软件,但是我一次都没能成功安装好Project
Server,太悲剧了。就是一个不错的项目进度管理工具,是完全基于WEB的,可惜是收费而且全英文的。Project的主要功能我认为有2个,一个是关于资源的自动计算,一个是自动勾画的甘特图。但是软件开发往往小任务、突发任务很多,碰到的延期和别的乱七八糟的事也多,所以严格描述开发流程,是一个非常困难的任务,就算你用Project也是一样。所以一般来说Project适合描述一些比较大粒度的计划,如果资源细到人,项目细到模块,这个Project文件将会是维护的无底洞。
少花些时间在Project表的制订上,而多一些花时间来通过面谈和测试来掌握进度。
&&&&&&&&&&&&&&&&&&&&&
iii.&&&&&&&&&&&&&
版本任务列表/墙
现在流行的敏捷开发,都有提到“项目仪表板”“任务墙”这些东东。然后每天早上开会大家来汇报一下任务的进度情况。对于这种实践,我觉得没有什么突出的好处,也没有什么突出的坏处。
但是把版本任务都放到墙上,本身能提供一定的激励作用,这个做法本身也是逼迫管理者一定要明确版本目标,筛选需求。与其说是给开发成员看的,不如说是给管理人员的限制。因此这种东东,还是很有必要的。
本节列举了大量软件开发的“软件工具”,但是肯定还会有更多的软件工具出现,我认为使用某个工具,在某个工具投入精力和资源,是应该有明确的辨识原则的:这个工具,一定要能节省程序员的注意力,而不一定是节省时间或者现金开支。因此能够减少非编码和写文档的操作,能自动化就自动化,就算为了这个事需要耽误一些开发时间,最后也是很补回来的。而有一些工具,看起来很帅,但是需要分散程序员的注意力去搞,就是不值得使用的。
软件通常都需要经过很多人和很多次的沟通才能生产出来,但是沟通本身又往往会影响软件的开发速度。这是一段很矛盾的关系。好的沟通方法能降低开发中因为信息不透明导致的开发资源浪费,而又尽量减少沟通所占用的精力。
&&&&&&&&&&&&&&&&&&&&&&&&
i.&&&&&&&&&&&&&
在任何一个软件产品中,如何应对需求的变更,都是至关重要的。需求一直是软件工作得以成功或者失败的最重要因素。软件开发中很多技术和方法都是围绕着需求来设计的。
需求的沟通是需求工作的第一个环节。首先沟通的对象必须是经过挑选的,以免添加不必要的需求混乱。最佳的需求沟通是和用户或者用户代表。但是他们往往他们缺乏必要的计算机知识。而程序员却很少有丰富的需求领域的知识。这个鸿沟需要双方共同去弥补,最重要的做法是,不要光靠口说。
程序员应该认真研究需求领域的知识,仔细查看涉及的单据、原型产品、现有工作流程等,而且必须用笔记录下来,之后再去整理问题,逐条咨询用户。在仔细了解情况之前,不宜开始设计整体程序结构。
当你有一定了解之后,程序员就可以动手开发一个快速的原型,如果没有足够资源,一组界面图也是很好的。以程序的外观来帮助用户来协助设计,是最有力的需求沟通方式之一。不断的在用户的帮助下完善这些界面图,标识上那些可能需要的数据和流程,然后完善,然后再继续找用户确认。这个过程在前期可能会相当枯燥,因为那些沟通用的原型也许一点都不会给后续的开发带来重用。但是能明确需求,却是对开发最大帮组。
&&&&&&&&&&&&&&&&&&&&&&
ii.&&&&&&&&&&&&&
在需求基本有一个思路之后,需要开始准备需求评审。首先说说评审的材料,一般会是《用例图》,《领域建模的模型》,用例规约,一些《非功能需求点列表》,甚至软件的一些经过用户确认的使用流程和使用界面。
评审的过程其实远没有沟通的过程重要。这个环节主要是给大家一个明确的开端:现在我们开始做系统设计了。作为在一些公司内部,需求评审是否得到通过还是产品是否能正式开始立项的一个流程。
对于评审,很多时候会认为是,提交评审者来写报告,然后向一堆专家或者上级来介绍,最后他们提出问题,幸运的话就盖章认可。但我认为评审不应该是这样的。因为如果上级和专家没有参与项目需求的沟通,他们对项目的了解是片面的,靠一些文档和口头介绍,一定会以“挑毛病”的姿态出现。而项目本身是否真的可行,却不负担真正的责任。
因此我认为需求评审应该是项目发起者,也就是有权拍板是不是做这个项目的人,来主持这个评审会议,所有的材料由他宣讲,疑问由他回答。而其他的与会者包括专家团和可能的开发团队,纷纷向他提出问题,以确认真正的可行性。最后主持者在搜集了众多意见后,筛选出有意义的意见,改善需求评审的材料,最后拍板是否完成需求评审。这种流程,无疑会要求公司的权力下放,而事实上,如果不是下放,又或者不是老板亲自主持,很多项目最后就输在了起跑线上。
&&&&&&&&&&&&&&&&&&&&&
iii.&&&&&&&&&&&&&
程序员的沟通讲求的是效率,准确是最重要的要素,如果无法表达“准确”,那就只是在创作,而非沟通。对于需要高度注意力的工作——开发软件来说,群体创作的效率实在不够高。因此提高沟通的“准确”程度是至关重要的效率因数。
开发中的沟通有很多种,其中最重要的一种是需求沟通。特别是作为技术人员,和策划、美术的沟通最多。这里需要重视的就是,和非技术人员沟通,快速原型:如假的界面图或者手画稿,填写了假数据的表格等等,是很重要的沟通手段。很多时候我都会要求把这些沟通过程中的手画稿扫描保留下来作为设计文档的一部分。
另外一种沟通是程序员之间的。我一直认为程序员之间最好的沟通就是“不用沟通”。客户端和服务端之间调整协议,最好的方法是直接两个IDE联调。关于工作任务的接口,最好是定义出接口代码,并且有单元测试针对接口代码做处理。当然拉,对于这些接口的设计,还是需要当面沟通的。
最后要说说会议。我认为沟通不应该打断开发。不管是5分钟还是1个小时,会议都是一种打断。而很多会议需要开前准备很多东西,大家试图用这种方法减少会议的时间,但实际上却占用了同样多的时间。我们应该关注如何减少会议,以及减少会议对开发的打断。在午餐的时候开会,我认为是一个比较好的方式,这种打断是天然的,不会产生额外的打断。而且与会者通常不会睡着。午餐时的讨论气氛也会比较好,比起一本正经的会议要活跃的多。
&&&&&&&&&&&&&&&&&&&&
iv.&&&&&&&&&&&&&
程序员和测试人员之间的沟通一定是密切与频繁的,虽然我们有JIRA、BugZilla之类的BUG跟踪系统,但是往往很多问题还是要通过口头的沟通来解决,我认为和测试人员的沟通关键是要分出优先级,对于“可重现”的BUG应该优先沟通,因为可以很快解决。而那些偶现的问题,可能沟通中一大半都会是猜测,其实可以先放后,这不表示那些问题不重要,而是应该在确定能解决的问题都先解决掉,这些时间内测试人员也可以努力把偶现变成必现。
测试沟通的内容中,对于“名词”一定要明确,因为我们会有很多个环境,必须要让每个概念有个清晰的表达方法。我们经常会在“测试”这个词上犯糊涂,比如“测试版”到底是哪个版本,“测试网”又是哪个网?甚至“测试机”是个PC还是个手机?这些都必须明确下来。比如用alpha网,beta网就清晰的多。
&&&&&&&&&&&&&&&&&&&&&&&&
i.&&&&&&&&&&&&&
设计意见搜集
负责设计方案的人必须负责搜集设计意见。我不赞成方案由下属设计,意见由下属向上级搜集。我认为方案应该由上级负责,而意见向下属争取。如果有一个上级并不负责设计方案,那么他也不应该有权力去“评审”这个方案。这样做看起来风险很大,因为我们很多的上级并不负责具体的“设计”工作,但是对比起上级提供一些不知道该怎么办的“指示”,而非要加到方案中去的情况,可能危害要少的多。
一般来说我们认为上级会比下属的经验更丰富,如果“无权”评审方案,就必须换一种工作方式:要不自己来做设计,要不采用建议的方式说服下属——这样做的好处是能让上级对自己的概念讲解的更清晰、更细致。否则不足以说服下属。
&&&&&&&&&&&&&&&&&&&&&&
ii.&&&&&&&&&&&&&
设计评审的形式往往是一个结论是yes or
no的会议。但是实际上要用好这个沟通工具,却不能怎么简单。首先,方案的评审提交者应该是最后决定者,当然应该在一个机制的监督下决定。这个决定就是,对于与会者提出的问题,包括提交者提出的问题,都要有明确的答案。
与会者可能会与提交者就一些问题有分歧,但提交者会有最终决定权。这个机制听起来很荒谬,好像自己指定法律自己又可以修改。但是,实际的开发上,如果方案和执行者并不统一,最后执行者还是会有办法“规避”一些决策。这里也涉及一个重要的问题,就是要把权力给有能力承担他的人。不能想着只是让某些自己还不放心的人去做方案,然后试图在评审的时候“把关”了事。
最后把关固然比不把关要好,但是把关要避免成为扯皮或者阳奉阴违,就必须要权事统一。真正的把技术的知识灌输到底,这样会耗费指导者较多的精力,因为需要在提交评审前更多的沟通。当然了,虽然方案又提交者决策,但是,作为业绩考核和技能评定,上级还是可以针对这些设计方案来给出专业评判意见。对于非常顽固者,实际上也有一个“秋后算账”的“威慑”。
设计方案,也是开发者的一个重要输出,代表了开发者的技术水平和工作绩效。
对于设计方案的组成部分,下面架构设计章节会有更多的讨论。
&&&&&&&&&&&&&&&&&&&&&&&&
i.&&&&&&&&&&&&&
单元测试的好处是让你在设计代码之前,就要考虑别人如何去使用你的代码。代码的可读性是建立在读者的前提上的,如果强迫第一个读者和使用者就是作者本人,那么在设计API和接口部分,就会考虑更少的耦合。因为强耦合会让单元测试非常难写。IDE和单元测试结合是一个很好的实践,虽然并不能节省多少输入的代码量,但起码会给与一个正式的环境。
每个细节组成部分的正确性测试,会增强你重构代码的信心。对于单元测试,我认为最少应该覆盖所有正确的路径,以及重点防御的错误路径。对于覆盖了这些重点关注的地方之后,放开手重构代码就很方便了。虽然很多语言能通过编译就已经消灭了很多的BUG,但是起码还是要运行一下。而单元测试可以分区域的运行完成的代码,避免的整个系统一起运行,突然爆发一长队的错误,让DEBUG工作无从入手。
单元测试应该是代码的一部分,和源代码一起存放。自动构建时也应该进行检查输出结果。通常提交代码的时候都会自动运行单元测试,但是当版本树有分支合并的时候,单元测试尤为重要,而最重要的是在分支上建立的单元测试,这些测试会大大加强系统的稳定性,因为检验了“合并”功能产生的代码——这些代码是最容易出错的。
&&&&&&&&&&&&&&&&&&&&&&
ii.&&&&&&&&&&&&&
系统测试的自动化程度决定了其重要性。系统测试一定要先办法找到测试的“切入点”,如对WEB系统测试,使用HTTP请求列表作为测试发起事件。对于WINDOWS测试,则使用窗口消息。对于服务器,使用协议包。一定要想办法把手工操作“记录”成可编程控制的操作。第二个重点就是要有办法用程序鉴别测试目标的输出,这里可能会用到正则表达式,词法分析,图形辨认等,但是如果一个好的系统设计,在考虑到测试时候,应该设计出尽量简单的测试输出点数据。如一些结构化网络数据,或者客户端数据中的模型数据等。
系统测试的环境自动化部署是关键,其中测试数据还原也很重要。一般系统测试需要反复执行——每次发版本都要。而测试结果很多和数据结果有关,因此一定要有办法把系统的数据(数据库内容)还原成每次测试的初始状态。这个在建立系统测试的环境的时候就应该考虑,并且做成每次测试执行前都自动还原数据,否则最后的“断言”测试很可能会失败。
&&&&&&&&&&&&&&&&&&&&&
iii.&&&&&&&&&&&&&
我们必须要做压力测试。因为我们要提供有限服务。服务器或者客户端都应该对系统的最大能力值有一个设定,然后通过压力测试获得最可靠的数据,用以设定这个值。这样能保证程序在合理环境下正常运行。
压力测试可以通过搜集、复制产生数据。比如服务器可以记录网络请求包,然后按会话记录成一个个队列,最后通过并发一起回访,就可以模拟多人同时的情况。如果还不够压力,可以复制队列,然后修改一些互斥数据(如用户ID),产生更大的并发压力。这种测试往往能很真实的反应情况,缺点是必须要搜集一定的用户操作。但是我觉得公司一般的QA的操作就是很好的复制源。
压力测试如果用自己构建的压力数据,需要注意的事项:密度、顺序、覆盖率。有时候需要自己构造压力数据,我认为最少应该有几个可输入的调控相:每秒并发发起多少请求,每个请求的间隔时间;每个请求的顺序是否按预定顺序排列好(因为有的操作是需要先后次序的),请求包是否覆盖了系统的所有处理逻辑,而覆盖的密度比例是否和真实的环境大体类似。如各种协议格式的包,是否按外网的比例来产生。
压力测试必须要注意专用环境:带宽、磁盘、硬件、测试数据还原。高速的局域网,最好和办公网分开,否则会影响工作。磁盘要清空足够大,否则可能会让日志把磁盘填满。要用专用的测试硬件,以免造成别的工作数据的破坏——同时也提供了性能指标的硬件基准,这个尤其重要。压测的数据包数量巨大,一定会产生巨大的持久性数据,为了可以重复操作,这些数据一定要能自动还原。同时也是保证自动化重复压力测试的需要。
&&&&&&&&&&&&&&&&&&&&&&&&
i.&&&&&&&&&&&&&
KISS:保持简单。需求之所以复杂,是因为人的思想难以界定,充满了是和否的中间地带。所以第一原则是:只承认确定是的需求。未来的需求暂时不考虑,在第一批需求完成后,真实的第二批需求就会确定下来。人类不可能未卜先知,所以不要妄想一开始就能准确的预测需求,只需要把确定的需求理解清楚,就打下了基础。以学习的心态去了解需求,不要被固定的合同束缚,才真正能跨过需求的第一关。软件领域最大的、永恒的挑战,正是需求变更!
面向对象分析:寻求领域概念。计算机把世界抽象为0和1的序列,这种方式也影响了程序员。但是世界是复杂而多变的。固定的数据建模已经被证明了无法很好的应对需求变更,所以真正的方法应该是去先认识世界,对于业务领域中的概念做学习和界定,然后用面向对象的方法去框起来。这样“对象”和现实世界与0、1之间,就搭起了一个人类可以理解的桥梁。因此我们的需求应该从领域模型出发,使用业务领域的名词作为系统中对象的名词,尽量用对象去“描述”这个领域中的概念,而不是急着去完成一个个概念供使用者交互的“流程”。
需求分析有很多工具,如领域建模。UML中的用例图和用例规约。针对非功能需求的“场景-决策”表格。还有著名的鲁棒图,可以转变成UML的模块图。这些都是值得学习的需求分析工具。而且不会太花费时间。
&&&&&&&&&&&&&&&&&&&&&&
ii.&&&&&&&&&&&&&
这个方面《编写可读性代码的艺术(ARC)》里面说的已经很详细。只需要认真的按照里面所说的去做就可以了。
另外有一些惯例,我觉得明确一点的好:
关于英文缩写命名,为了简单,一般只取前三个非元音字母为好,而且单词长度超过5个字母的才缩写。
对于C++这类兼容过程式的语言,如果是过程式的变量或函数,应该采用下划线连接小写单词,如arg_num,
get_file_name(),如果是和类与对象相关的,包括属性、方法,就采用JAVA风格的命名,如argNum,
getFileName()。
&&&&&&&&&&&&&&&&&&&&&
iii.&&&&&&&&&&&&&
理论上代码重用这是个大话题,不应该放在这么小的位置来说。但是实际上软件开发很多地方都涉及重用。所以这里只提一些我认为最重要的:能下载到的代码绝不开发。——事实上很多程序员都以重新发明轮子为荣,并且都认为别人的轮子不好用,比如鄙视STL的C程序员比比皆是。我认为老板给你的工资很多时候并不包括重新发明轮子,不管你觉得怎样,学会使用已有的轮子都是一个程序的义务。否则等于浪费老板的投资,对于自己来说虽然好像技术长进了,但是整个项目都被你脱了后腿。与其你自己去写STL,不如去认真读一读STL源码,掌握它的内容,然后教更多的程序员去用他。否则我怀疑最后你只能去写汇编了,那就随便你了。
代码重用往往和机器性能有一定冲突,但是在我看来,很少项目因为性能差那么一点点而挂掉。但是因为代码开发效率太低,跟不上项目需求变化而挂掉的项目多的多。所以那些只以性能作为技术水平标杆的程序员,某些时候是项目的毒瘤!
&&&&&&&&&&&&&&&&&&&&
iv.&&&&&&&&&&&&&
过程式:C语言
结构化编程当中,最重要的设计方法是:自顶而下,逐步细化。无论你是否在写过程式范式的代码,这个方法都应该遵守,否则一定会出现划分粒度不一,难以重用的代码块。大部分的巨大函数体都是忽略这个原则造成的。
一般来说C语言会要求对一个内存进行操作,并且反应执行结果在其之上。所以通常都会有一个类似g_Env之类的全局变量,用来存放多个过程需要的数据。为了避免多个函数需要反复的通过不同的输入参数和返回值来“串接”调用,通常都会设计成一起去修改
g_Env变量。
同时也会有一个g_Cfg的全局变量充当配置文件。面向过程的代码则很少使用全局变量作为“操作台”来处理数据,因为都被封装到对象里面了。
C语言的回调模式一般通过函数指针来实现,这个几乎是做框架代码的最好用的方法。而面向对象则采用多态来取代函数指针,会更安全一些。
对于函数的返回值,一般来说不会用来真正的“返回”某些数据,而是返回的是处理的结果是否正常\异常。而处理结果的数据往往通过输入参数(指针)来得到,这个是和面向对象代码很大的区别。面向对象的语言一般支持异常,取代了返回值的“错误报告”功能,而返回值则真正是一个处理的结果。这样减少了输入参数,会让API更容易使用,符合理解习惯,也更不容易出错。
总体来说,注意抽象好函数的层次,使用统一的,尽量少一点的全局变量,使用函数指针实现回调,使用返回值作为函数的错误报告,使用输入参数,就是过程式C语言的主要特点。
OO:设计模式
对于封装、多态、继承的玩法,最后演变成GOF23种设计模式。说到底都是为了实现几个主要的原则,其中最关键的就是“开闭原则”。这方面的书籍也是汗牛充栋,特别需要关注的是《重构:改善既有代码的设计》。
面向对象编程方式是现在最利用适应需求变化的一种技术。包括泛型这种静态化的对象技术。所以无论什么原因,都应该掌握一定的这方面知识。
面向对象设计范式的核心点是去描述现实世界的概念,而非用算法和数据去模拟这个世界的运行。因为关注点在概念这种名词特征上,所以可以先初略后精致的逐步细化设计,正好符合需求变化的特征。
动态模式:JS/PHP/PYTHON……
动态类型语言以其极致快速的开发效率,容易掌握的语法而闻名。其中最能提高效率的是动态数据类型。减少了大量的声明、定义和局限的代码。甚至减少了大量的数据结构的使用。如PHP里面所有的数组都是哈希表,而JS/PYTHON里面的Object就是哈希表。实际上AS3.0也是有类似的特性。更好的利用这些语法糖和数据类型是提高开发效率的关键。所以我也反对在这类语言里面自己重新包装一套类似C语言的数据结构或者容器类库,实在是没必要。
动态类型语言另外一个特点是脚本化解释运行,不需要维护堆栈,也不需要考虑编译的定义。甚至还有交互式终端一行行的去命令式运行代码。把尽量多的业务逻辑的处理细节“过程”用动态类型语言(脚本)来执行,是提高开发效率的重要手段。如果你比较一下用C语言编写CGI和PHP比较一下,你就知道效率相差有多少了。
特定领域:SQL/SHELL
SQL这类语言和一般的语言有比较大的设计差别,他更多的设计为“表示”而非“命令,所以需要另外一种思考方式。而这类语言因为和领域结合很紧,所以是强大的领域工具,包括SHELL和AWK这种脚本语言,具备别的语言非常费劲才能实现的功能。在这些领域,尽量使用这些语言会有事半功倍的功效。
SQL中的函数和存储过程,是强大的工具,有时候整个统计系统都可以直接在数据库里面运行。而很多运维的系统工具,用shell来实现则会简单高效,因为需要操作的功能是操作系统本身。
函数式:强大的数学表达力
Lisp,schema,erlang这些函数式语言,采用链表来描述一切,只需要栈而无需堆,用递归代替循环,这些都很符合多核并行运行的要求,而且还能很方便的中断和恢复程序运行。在业务需求变化较少的,而计算任务比较多的场景,是一种非常强悍的编程工具。对此我了解不是很多,但是很希望有机会能用函数式语言做一个东西看看。
构建-集成-部署-测试
版本管理-构建脚本-自动构建-构建包管理:
所有的源代码都必须进入版本管理;所有的构建、部署、测试脚本也需要进入版本管理,所有的一切都应该进入版本管理。一个构建系统的运行,应该是可以完全从版本管理服务器上重建一切的。
Hudson是一个很好的自动构建服务器,但是构建脚本你还是需要自己去写。确保你的脚本可以从零开始构建,并且在所有你可能碰到的平台上正常构建,如32位和64位系统。
构建出来的软件包,应该让hudson这类系统自动发布给所有相关的人,而且可以很方便的通过网络获取到,如HTTP或者SVN。并且需要保留多个历史版本以备回滚。
部署脚本-部署环境-自动部署
部署脚本往往是用动态语言写成,还会带有数据库操作等复杂的内容,因此必须也纳入版本管理。部署环境应该是足够安全而且和生产环境有足够快速的网络连接的。有了这些保障,才最后有自动部署的可能性。最好就是有一个部署服务器是和生产环境和办公网络,都属于内网(局域网)连接的。简单的自动部署工具必须要运维人员能掌握,并且取消开发人员的使用权限,避免开发人员直接修改线上服务产生的故障。
各类测试-自动测试-结果报告
代码提交前应该运行完成单元测试,代码在自动构建以及自动部署后,应该自动运行一定的系统测试脚本,结果放置到构建报告中。
一般来说,测试环境有几种:开发环境、内测环境、外测环境、运营环境
在开发环境应该是单元测试的运行环境。内测环境则应该是在自动部署后的其中一个环境,用以和产品人员沟通和验证基本功能。外测环境应该和运营环境尽量一致,自动部署后,所有的测试失败和人员手工测试缺陷,都应该视之为BUG进入跟踪系统。而且外测环境应该是运维人员的工作范围,不应该让开发人员上去捣鼓。经过了这三层的测试环境,不管是代码功能还是部署设置,应该都能自动化的在运营环境上可靠的运行了。
两顶帽子:加功能、改结构
关于重构有很多经典的书籍可以参考,比如《重构:改善既有代码的设计》《重构与模式》。但其中很重要的一点,就是重构的时候禁止添加新的特性,因为会让代码在修改的时候陷入复杂的“连锁”修改,从而让重构困难增加。同时如果你修改了特性,也需要新的单元测试来保障重构的正确性,这些都是自己搅合自己的做法。而在增加特性的时候最好也不要重构,因为你在努力通过测试的时候,也是在整理和验证需求。只有需求确定了,重构的目标才会清晰。
单元测试的重要性
重构的一个最大的困难,就是怕改的代码太多,从而出现BUG。但是如果你有一个覆盖率很高的单元测试集合,你就可以比较放心的去修改代码,因为一旦出错你立刻就能知道。当然有很多时候单元测试并非万能,有些情况单元测试确实无法覆盖,或者架设测试本身比较复杂。所以说重构还是一个比较高风险的动作。测试的工作本身是重构成功的最重要保障。
明确重构目标
很多时候重构起源于某些需求难以加入现有系统,但是如果只以这个作为重构目标,往往结果并非完全让人满意。实际上重构的目标应该是一个对于需求变更的总结以及前瞻。某些时候是以实现某种设计模式作为重构的目标。而选取的模式就是对于需求分析的结果。重构中目标的选取是至关重要的,这个需要对业务和技术有深入的理解,从另外一个角度看,重构目标和一开始的设计工作是同等的工作。所以说软件开发的“架构设计”实际上是持续在进行的。
加班的原因:学习、体力活
程序员的加班司空见惯,究其原因,有两种,一种是不知道如何实现,另外一种是工作量大。
对于第一种情况,有些人会写一堆代码然后调试,发现不对又改。而我建议是应该把“不确定”的部分,设计一些代码片段功能(单元),然后使用单元测试作为验证,通过逐步掌握这些功能,最后形成可重用的代码。这会是最节省时间的方法。
对于第二种情况,应该多考虑设计一些工具。比如使用一些脚本语言来代替一些数据的体力活,尝试抽取可重用代码来简化逻辑。做这些可能一开始会比较费时间,但是长期来看,却是可以节省下大量的加班时间。
实际每个程序员都知道生命宝贵,并不会有意的拖延工期,除非觉得这个工作实在是不值得去做。所以因为进度原因导致的强制加班,最后都会被“减班”还回来。损失比不加班还要大。《人件》里对于这个有详细的论述,我也不去重复了。
如果是自愿性加班,本节会有用。如果是被迫性加班,实际上是无论如何不会增加整体的开发效率。所以如果真的要用加班这招,最重要的是变“被迫”为“自愿”。
如果作为团队领导者,你看到整个团队已经能在每天6小时内高效的工作,再强迫加班最后只能是降低开发速度。原因不再细速,可以参考《人件》。因此,如何让团队加班的方法,应该改成如何让团队不用加班的思考。改进开发工具,提高开发技术,加强团队建设,这些都是有效的方法,唯一需要避免的就是如何“强迫”团队加班。
避免加班的方法:思考设计、学习提高工作效率的方法、在上班时间内加班
根据我的经验,如果一个程序员一天有6小时都高度注意力的做开发,实际上开发效率已经可以达到很高,而很多一天工作12小时的程序员,其高度注意力时间往往只有4个小时。所以不加班完全是可能的,除去别的因数,对于个人来说,避免自己玩死自己是最用的知识。在动手之前先仔细考虑清楚细节,可以避免后期逻辑BUG的折磨,这种BUG是最难调试的。而学习各种工具以及关注代码在提高开发效率上的知识,则是另外一个重要的手段。因此再次吐槽那些不重视开发效率的程序员,你们轻视面向对象,轻视软件工程知识,轻视那些对程序性能无关的知识,最后的苦果就是——一辈子加班!
程序员的状态起伏
【设计-编码-调试-总结】的循环
程序员在开发程序的过程中,往往会经历以上几个阶段,在编码阶段是状态的高峰,调试阶段开始陷入痛苦,很多时候会跳过总结。整个循环完成后,则是疲惫不堪,注意力无法集中。因此我们可以注意几个重要的环节,减轻这些压力。
首先设计阶段如果能尽快热身,直接更专注的深入细节,则会避免无休止的修改方案,对于开发的指导也会更明确。而编码环节采用更多的工具和技巧减少体力和脑力的消耗。如果设计阶段和编码阶段的工作能关注代码可读性和结构,最后的调试往往也不会非常困难,然后为了奖励一下自己,可以写一点总结。
打破循环造成的心理影响
如果在每个阶段中能尽量多的融入下一个阶段的工作,同样也可以起到降低压力的作用。比如在设计阶段就把很多重要的代码命名工作做了,在编码的时候就顺手解决所有的语法错误,调试阶段的测试用例就可以用来作为工作汇报的材料。
避免疲劳战术的方案:缩小循环体
在开发的循环中,每个阶段越长,最后的疲劳就会越大,而每个过程越短,则越容易被接受。所以尽量在设计阶段划分的细致一些,可以明显的降低后续的工作压力。缩小开发流程也是敏捷开发模式的重要观点。这对需求分析、代码结构、测试技巧都有很高的要求。重视这些知识,就会明显的降低工作压力。
逻辑架构主要是为了明确需求而做的设计。针对需求以及需求变化作为架构目标。因此逻辑架构在架构设计中,是对于提高程序员生存率最至关重要的一个设计。采用合理的逻辑架构,将会大大降低需求变更对开发的延迟作用。逻辑架构最直接指导代码中互相耦合的情况,仔细设计好耦合的规则,会让后续开发事半功倍。
逻辑架构的经典模式有《POSA》中指出的几种,其中以分层和微核模式最为常用。MVC和管道过滤器模式则在特定系统中是最优模式。后续基于分布系统的SoA等架构模式,则多是建立在分层的基础上。分层模式可以按需求关注点来划分层次,因此可以安排不同经验水平的程序员分别承担。微核模式则直接按具体功能划分代码,适合水平相差不大的团队进行功能的并行开发,因为可以单独测试。
不管何种逻辑架构,都是把功能-代码划分成多个不同的部分。这些部分通过一定的规则互相耦合。这提供了最好的工作量划分依据,以及互相之间的接口定义。由于存在接口定义,将来人员流动的时候,也可以根据接口来理解代码模块的逻辑。良好的工作划分,能极大的降低程序员之间的低效沟通,使得工作能被多个人同时推进,而工作能被同时推进,则是软件项目能利用好人力资源最直接原因。
需要指出的是,很多使用非面向对象语言的项目,特别是C语言项目,非常蔑视进行逻辑架构设计,因为所谓结构化编程其实约束很少,而大家往往直接忽略掉。这是非常大的问题,导致一些复杂的“过程”最后完全无法维护。有很多项目到最后不管如何增加人手,都无法提高开发速度,就是因为实际那些代码无法利用更多的人力,反而增加了更多的沟通成本,架构直接降低了开发效率——往进度落后的项目增加人手,只会让进度更见落后。
运行架构主要是为了解决运行时的质量需求,主要分为性能需求和可用性需求。系统的性能需求除了在代码内部通过算法来提高,往往还要采用缓存和并行的方式来扩展。这就涉及到程序的运行时设计,如数据处理流,多进程间通讯,数据的多种格式转化。对于可用性,实际上也是通过并行热备的方法来实现,因此运行时的各种控制命令、地址、消息数据流也是运行架构需要考虑的。
运行架构一旦确定,等于大部分的“实现”代码确定了下来,设计一个有足够扩展性和可用性的运行架构,可以减少后期为了扩展性能或提供可用性做更多的代码。而且也降低了系统在运行期对开发工作的干扰——正在运行系统出了问题,往往是在节假日或休息时间,都会迫使程序员回公司或者上线维护,极大的增加了开发人员的疲劳,同样会影响项目的进度。因此一开始就考虑可用性和性能扩展问题,并且实际的用代码去实现好,绝对是一个未雨绸缪的好方法。明智的项目经理会愿意在项目前期花多一些资源在这种“非功能性”方面的开发,从而得到一支士气水平稳定的开发团队。
通常运行架构需要至少设计一个可以水平扩展的接入层或逻辑层,以便通过增加服务器来提高性能扩展。因此也需要预先设计负载均衡的系统,如果是WEB系统,用DNS轮训是最简单方便的,如果是游戏类用户间交互比较强的,设计一个“目录服务器”用来提供客户接入地址是最少需要做的。
可用性架构中,最少要为逻辑服务器和数据库(持久层)服务器设计至少一个热备服务器,在机器断电或者机房断网的情况下,可以经过程序自己的检测机制,自动跳转到备份服务器上处理。一般数据库服务器mysql采用master-slave用来备用,而逻辑服务器则可以使用目录服务器来指定备份服务器地址。当然了,如果目录服务器也需要热备的话,则需要另外一些代码支持,如客户端本身就会去多次尝试不同的目录服务器。
一般有“架构设计”的系统都会有运行架构的设计,所以我并不认为需要如何强调其必要性,反而需要强调的是,系统架构设计,远远不止是运行架构的设计。
开发架构一般用于满足开发时质量需求,和逻辑架构有密切的关系。开发架构定义了源代码、二进制和发布包的文件、路径、负责人的划分和依赖关系。一个按照固定开发架构设计的系统,能方便的开发出持续集成的各种工具。
开发架构一般的主要呈现形式为SVN目录构造方式,或者在makefile、IDE的项目设置文件中。一个软件通常分成多个不同的“系统”或者“项目”。很多如Eclipse需要每个项目只存在一个执行入口main(),所以开发架构在这种情况下同时也收到运行时架构的进程设计限制。
一般来说功能相对独立的代码会成为一个“模块”或者“系统”(项目),通过提供程序链接接口,如DLL,.a和.h文件,JAR文件,或者SWF文件来提供。这个粒度的划分有多种标准,如按功能的,按开发者的。但是有一个通用的准则,就是如果已经设计的不同“模块”中都有调用同一个或者类似的代码块。这块代码就有资格自己成为一个平行的“模块”,以便日后修BUG可以单独升级。
个人比较喜欢按业务功能的层次来划分模块,这样有利于划分任务,减少代码互相影响,最重要的是比较容易让人理解。但是就必须经常把工具类模块协商抽取成为“公共模块”。
部署架构对于持续集成,降低程序员的运营期压力,有至关重要的作用。一个好的部署架构可以提高性能和可用性。让程序员可以按部就班的去解决问题。
运行时架构在软件层面提供性能和可用性。而部署架构考虑的更多是硬件层面。比如网络机房的分布,服务器硬件的搭配,监控和维护工具软件的安装。开发测试网络和运营网络的设置。关于安全性的配置。
几个比较明确的经验是:
1)& 尽量靠近用户部署机房
2)& 所有机房间应该有一条专用的局域网链路,让服务器间数据可以有专用线路可用。
运营网络的防火墙对于公网接口设置为只开启服务端口,运营和维护端口全部放在局域网线路上。
开发办公网络不能直接和服务器的局域网直接连接,降低个人PC被入侵造成的影响。所有运营网络的服务器都必须限定有限IP的机器去连接远程登录,并且这些机器需要是LINUX的。
对于服务器硬件按照磁盘IO密集型、网络IO密集型、计算密集型、存储空间大需求型、经济节省型的分为5种型号,由业务技术人员仔细选择。
在测试、开发、管理等资源要求很小的服务器上,尽量采用虚拟机,最大化利用硬件,同时减少维护成本。
对于日常服务器的维护和监控,建立报警和预警机制,如磁盘、带宽、CPU、特定进程、监听端口。
对于机器和带宽的部署,采用最少可用性保障的策略,就是最少有2份服务器以及2倍预计带宽需求(或其他需求)。
对于部署过程需要的脚本、配置文件、安装包,必须要有自己独立的SVN或者文件服务器管理。同时也需要建立“自动化”部署的工具。在这些工具完成之前,不应该正式对外运营。而部署工具本身应该在“外测”环境下经过详细测试,才更新到正式运营网络上。
数据架构对于任何业务都有很重要的影响。对于用户产生的数据,架构本身需要容易备份和恢复,数据就是财富,而数据架构是存放财富的方案。对于开发团队产生的数据,则需要完善和方便的管理工具,便于修改和增加这些数据。
数据架构本身还涉及性能、易用性等多个方面。一般来说分为使用关系型数据库和不使用关系型数据库两种。但是不管那种,对于数据的备份(热备)和恢复都是最首要应该考虑的问题。数据的结构过于复杂其实不利于备份和恢复。而很多时候大数据量又产生“分区”需求(分库分表),这是分布数据存储的课题。
对于使用关系型数据的,一般需要依赖数据库服务器自己的热备功能和分区功能,或者自己去实现。然后使用ORM软件来操作这些数据。所以关系型数据不宜做的过于复杂,太多的“外联”表会让整件事变得很复杂。
如果不使用关系型数据库,现在的NoSQL风潮提供了很多可选的方案,这些方案最大的特点就是对于结构复杂的数据有良好的扩展性,对于大数据量也有优秀的扩展功能——重要的是不用你自己去代码实现。缺点则是可能无法保证“统一性”。比较实际的观点是,尽量少使用关系型数据。虽然它的概念已经深入人心。
每个模块都可以做架构设计
上面的几个架构,基本包含了整个软件架构应该涉及的方面。而我们往往比较重视一些“大项目”的架构设计,而比较忽视一些中小项目的架构设计。实际上大部分项目并非“大项目”,而大型项目本身也很可能划分成更小一点的项目来外包,所以我们应该对于每个项目,都以架构设计的观点去分析和设计,只是不需要陷入文档的案牍之中就好了。
一些好的架构设计,也可以在多个模块和项目中共用。这种共用的好处非常多,一个是可以节省开发时间,另外也可以少走以前的弯路。最重要的是如果积累下这种设计的文档和思想,可以让整个团队的开发效率都得到提高。
目标管理是现代管理学的一个重要成果。明确团队的目标,然后让所有人都理解并认同这个目标,是管理中最重要的工作。只有每个人明确了目标,才可能发挥出他的主观能动性。而且要有明确的目标,团队成员之间才可能合作。否则成员之间可能会互相拆台或者推卸责任。
目标应该是整个团队的目标,而不应该是只划分到个人,因为这样不利于团队的整合,而会形成严重的个人主义。当然我们最常见的是团队中对于目标不明确。
目标应该包括以下内容,才称得上明确。首先是项目要满足的市场需求,这是项目的愿景。其次是项目怎样才叫做的好的标准,一般是和竞争对手比较的结果。最后是项目目标和个人发展之间的关系。三层目标必须都让每个人明确和认同,才能真正激发出团队的动力来。
市场需求如果大家不认可,就会觉得项目不值得做,这个时候就需要领导者来用数据和事实证明给大家看。
项目优秀的标准,不可无限拔高或者虚无缥缈,明确的竞争对手数据是最好的标准,虽然这个信息通常很难获得,但是这个是团队中非常有凝聚力的信息。应该尽量的获取,然后公布给团队。
每个人和项目成败的关键,则是核心的激励机制,虽然很多时候开始很难明确到金钱上的奖励,但是应该起码提供一个“最好情况下”的许诺。很多项目以收益分红,或者过程评价来加工资作为明确的激励。
人在集体中能发挥的作用必然比单个人要大,这是人类作为群居动物的天性所决定的。如果你有一定的工作经验,必定会体会过一个团结的团队所发挥的良好作用。如何能构造起一个真正的高效的团队,我认为最重要的方法是“沟通”。这种沟通必须是全方位的,包括团队成员之间的私交,他们互相之间在工作能力、人品性格、兴趣爱好方面的了解。在管理者和团队之间,对于项目前景、公司状况等一切和团队切身利益相关的方面的信息,都必须有良好的沟通。如果程序员觉得你在隐瞒些东西,你一定就是在某些方面有所保留。这种猜忌会破坏团队的形成。所以对于大量看起来是“保密”的信息上面,对团队尽量多的公开,是能让团队得到主人翁感觉的重要手段。传统管理方法中很多时候强调公司的信息保密,个人对于团队的效忠。而这些在高科技开发企业中是行不通的,因为他们就掌握着公司的最大机密——产品开发。
管理者除了对“人”做事,直接做事也必不可少,开发工作有很多方面是在做设计,所以开发工作本身并不是所谓的体力活,而是一些精巧的设计工作。除了自己参与开发工作,对于团队其他部分的设计工作,特别是其中的重要决策,管理者也需要尽量多的参与。一方面这种参与可以培训团队成员,另外一方面能加强对于项目控制。在决策的过程中,通过广泛的讨论,也是团结团队的一个手段。当然刚愎自用的处理方法就会产生反效果。
因为程序开发本身是一种高度自律型的工作,所以管理者的“不做”比“做”更重要,而且应该提供不受干扰的环境。在程序员注意高度集中的情况下,工作效率是最高的。试图不断的“参与”开发而打断程序员的工作,其实是在降低工作效率。好的管理者应该能让程序员沉浸在开发工作当中,完全不去考虑什么进度报告,工作汇报之类的事情。
因为程序员对于电脑的熟悉,所以经常会把一些别“专业”的行当混合起来交给程序去做。比如写代码的同事去处理数据库,由或者让程序员同事负责运维服务器和网络……术业有专精,如果一个程序员专心的做数据库的工作,他会比同时做其他几个事情做的更好。更不用说让程序员去夹网线搬箱子这些了。总体来说,提供资源支持,降低团队的“非专业”精力消耗。
按照专业领域分工;专业再细分分工;软件开发团队应该学习外科医生的团队,采用严格的分工合作,来降低混乱的沟通。每个人只负责自己的事情,会做的非常好。因此如果程序能很好的分成5个模块,就使用5个程序员,然后为他们配上专业的秘书,数据库管理员,测试人员,项目经理,运维人员,IT人员,以及其他的资源处理人员,比如美术资源处理专员。
关注工作分切点的协议,因为人力分工是提高效率的重要手段,所以人员之间的切分点——协议或者流程,就是很关键的东西。客户端和服务端程序员之间,通常就是直接的通讯协议,应该把通讯协议变成一种代码,然后双方都使用这种代码。客户端程序员和美术之间通常也应该使用某种基于软件工具的格式文件,比如是UI编辑器的结果。处理WEB的团队往往由美术提供图片,然后由专人切图变成HTML,而这个HTML文件就是很好的协议文件。有些数据录入人员使用JSON格式的文件,或者是某种严格定义的EXCEL文件作为协议文件。
很多团队喜欢“广播”方式的沟通,任何一个事情都让所有人在一个QQ群里面看到,或者任何一个事情都抄送邮件给一堆人。实际上这种沟通只会浪费别人的时间,所以管理者应该降低沟通范围,减少“噪音”。
绩效考核应该考核做了什么事,而不是做的怎么样;这个和很多按“结果”管理的老板很不接受。但是如果你只是想把绩效考核作为一个发奖金的机制的话,单独使用奖金考核机制就可以了。绩效考核应该是推动别人去做某件事的工具。对于已经明确的方法或者子目标,通过这种细化的方式去指导下属工作。因为是需要事后算账的,而且是量化的,所以下属会对这个事情很认真,同时那些不好量化的事情,管理者也很难执行绩效考核。所以对于“去做某些事”,是绩效考核最好的目标。
通过考核结果提供正式的工作方法意见。绩效考核本身有个反馈的过程,这个反馈的过程应该提供给下属针对每个具体事情的建议。这种具体的,单独的一对一的指导,会提高团队的稳定性。而且也让团队成员获得“受关注”的感觉。这种感觉是形成高效团队的重要工具。
考核不能代替目标,不能阻碍目标,而应该是一个沟通工具。绩效考核通常会涉及大量的文档工作,也会有很多量化的工作,但是这些工作,往往不能完全代表商业目标的完成情况。所以有些时候只是平白的增加了管理工作量。绩效考核的设定首要需要考虑是不能阻碍团队目标的实现。很多时候甚至难以覆盖目标。所以绩效考核应该是成为一种沟通的工具:定时、定量、定人的交换对于工作方法的意见。
目标达成情况作为考核的客观指标,但不应该是主要绩效考核指标。最简单的绩效考核指标就是收入或者利润率。但是这种简单指标除了在动机上提高下属的工作热情外,并没有从方法和经验上帮助团队成员。有效的考核是引导下属安装更有经验的方法去实现目标。
通过测试来了解进度;一切软件的开发,如果无法测试,就是无法了解的。没有人回去通过读代码了解项目的进度。所以项目本身必须具备经常提供“可测试”的功能。一旦进入测试,项目完成的数量和质量都立刻一目了然了。
用提高工作效率和提供资源的方法推进进度,而不是通过加班。加班是最有效的降低工作效率的方法。只有降低本身进度推进的损耗——内耗,改善工作方法——更好的工具和更多的知识,除此之外很难有别的加快进度的手段。但是,你也可以通过增加更多的资源,比如人力或者机器。如何把资源放在合理的地方,本身是一门学问,本文在上面很多节都有提到如何有效的使用资源——人力和金钱。
庆祝每一个进度节点。团队需要鼓励,才能保持速度。庆祝本身又是凝聚团队的一个契机,让成员觉得在这群人中间能不断取得成功,本身就会增加互相合作的意愿。如果无端端搞一些团建活动,会让人觉得厌烦,但是庆祝进度节点,则大家都会认同,可能只是一起吃个饭,但是也是非常有效的一顿饭。
确保公布进度的目标,并且争取团队支持。进度的目标必须能达成共识,“无理”的目标实际上不能成为目标,团队从此也会陷入最差的状况——没有目标。所以进度目标本身需要让所有人理解并且愿意去努力。通过共同的进度目标,来促进团队中所有人的积极性——那些喜欢偷懒的家伙也会不好意思。
在重视质量的情况下推进进度,并且为质量牺牲一定的进度。项目质量是团队和个人为之“自豪”的重要因数。如果你想拥有具备荣誉感的团队,就需要为此付出一定代价,可能牺牲一些时间,来获得更好的产品质量,实际上这是个事半功倍的事情。因为产品质量在长期来看,还是能提供更好的效益的。进度压力如果造成太多的粗制滥造,会让后期的团队越来越没信心赶上进度。最后被迫推倒重来,或者陷入一个“长期的重构”工程中。这些都是缺乏远见导致的问题。
放松固定资产的预算,尽早投入固定资产预算。项目初期成本中有很大量的固定资产投入。而这些预算看起来可以用更便宜但是质量更差的替代品来替换。但是从长期来看,人力成本才是最重要的大头。而如果你的固定资产太少,也会难以招聘或者稳住最优秀的那批员工。优质的固定资产不但折旧率更低,而且能让程序员发挥出更好的功效,直接节省那些高额的人力成本。
收紧人力资源预算,重视10倍效率员工的作用。人员的沟通成本,是所有关于人员的成本中最高昂的。人越少,需要的沟通就越少。很多公司在发展期喜欢快速扩充团队,希望能抓住机会尽快占领市场。但是请记住,一个母亲怀一个孩子需要10个月,100个母亲去怀一个孩子,同样需要10个月。团队和项目的进度并非靠人的数量增加就能加快的。而且更重要的,优秀员工的工作效率最大可以比一般员工的效率高10倍以上,你只需要给他们5倍的工资,就能节省下另外50%的工资,同时还有不止50%的固定资产投入和其他费用。少而精的团队在更方面都比庞大良莠不齐的团队更有效率。
针对风险,不断修改预算,项目进度越后期,预算越准确。软件项目开发和拍电影一样,具备很高的风险。不但成本难以预料,而且收益也要最后才能知道。因此对于预算来说,不断的记录和回顾预算执行情况,以及其效率,修改现行预算方案,才能真正适合开发的进度。那种一年都按年度预算去执行的死板方法,是无法适应快速变化的软件开发项目的。
留出过冬的口粮,定出必须笼络的人员,尽早进入资金循环。软件项目风险之高,难以用其他行业完全类比。就算最著名的公司如微软、IBM也频频推出失败的产品。因此在资金上留有尽量大的余地非常重要,很多项目经历过濒死体验后,才能实现商业成功。软件项目能继续高效的开发下去,核心人员是至关重要的,让他们拥有足够的耐心和薪水,和项目继续下去,才有收获那天的希望。而降低风险的最好方法,则是尽快去接触风险,尽快让产品上市,让产品开始尝试赚钱,能让开发方向尽快明确到最实际的内容上来。团队内的争论和疑惑也会因为实际的财务数字而消散,大家的目标会更清晰——赚钱。
师徒制度预备人员流动。人员流动是不可避免的,就算你做到100分,还是会有别的原因导致程序员离职。因此除了在代码上提倡可读性和良好的结构,重视文档和过程记录,采用预备接替人员是很重要的手段。让资深程序员和一个学徒程序员一起工作,能尽快提高学徒程序员的能力,同时也让代码能有多一个人熟悉。在师傅离职后,徒弟就可以升职到师傅的地位,也是一种良性的激励。而徒弟对于这个代码的感情,是别人所无法比拟的。
尽早进入团队和项目估值,寻找合适的买家。项目除了直接到用户市场上去实现商业价值外,还应该看到,软件项目因为他的结构性和扩展性,往往会在更大的范围内具有价值。一些其他商业方向的公司或者投资人,可能会看重你的项目的扩展价值。而这些扩展价值需要一定时间来让别人认识到,因此对于管理者,在清晰的掌握项目的全面价值的情况下,尽早的介绍给潜在的投资人和客户,能让项目拥有更广阔的前景,从而降低其天然的风险。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 如何提高员工工作效率 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信