分类: IT职场
2011-12-28 00:43:46
最近网上一直比较热闹,“淋巴哥”老师拿出高丽棒子那种可以证明屈原、李时珍就是韩国人及端午节源自韩国的那种娱乐考究精神考究出了所有说他的书不好的人都是书托和骗子来,一时间圈内大哗;接着在博客园又掀起一股 Java 与 C# 的瑜亮之争,不可谓不热闹。不过作为普通的开发人员,这些事情都是相对较为遥远的事情,普通开发人员比较感兴趣的是如何提高自己的技术,增加自己的能力,以便在今后的工作中找到一个更好的职位,这两天周公也收到了一封一个工作了 2 年的 .NET 开发人员的邮件,在邮件中他谈到了自己的困惑不足,周公觉得他的现状有一定的普遍性,因此想在这里谈谈自己的经验和体会,原文如下(为了保护当事人隐私,去掉了一些个人信息):
周公:
我叫×××,是××××人。做.net的web开发已经2年多了。
前天去"飞信(新媒传信)"笔试+技术面试,很侥幸被我通过了,但今天上午去参加总监的复试,我被出局了。
今天灰不溜溜(周公注:似乎没有这个词,可能用“灰头土脸”比较恰当)的从大门走出来,真的感受到了从来没有的挫败感。
说下我学习.net的经过。我是07年10月份接触C#的,自己买了本C#基础教程自己看的。然后又买了本asp.net基础教程。就这样走上了.net之路。
为了能在08年毕业前找到一份理想的工作,我在08年2月份又去图书馆买了本apress小组出的关于.net2.0电子商务的书,这本书让我了解了3层架构。当然也凭借这本书我在4月份找到了工作。之后就在工作中学习成长,也感觉自己各方面能力还是蛮不错的。
到 了今年3月份后,我发现自己一直受困在目前的水平中,想要自我提高,很难很难。我知道要学的东西有一大堆,但我不知道该从何学起。自己每天看看着(周公 注:应为“看看这”),看看那,如果没有项目、没有环境。那就很不系统。我觉得如果想得到更好的提高,只有换个更好的环境,如果能跟着一些强者一起做项 目,那么就肯定能得到突破,学到很多东西。
然后我就开始"骑驴找马",想找给(周公注:应为“想找个”)好的团队,学到些真东西。
我不得不承认飞信的团队确实很好,初试我的2个技术人员都30岁左右,技术也都很强。但就项目中的功能或一般的基本原理,由于我有充足的准备,还算是过关了。
不过今天上午,总监对我的面试,让我感觉自己了解的实在是太少了。很多东西只知其一,不知其二。更多的东西只是知道(周公注:似乎应为“只是知道怎么用”),但并不知道原理,或者使用过。
就拿对方问个:C#各个版本间的差别是什么? .net各个版本间的差别? prototype和jQuery间的差别?
我就头疼了,说实话,一直用C#2.0,并没有很好的去了解各版本间的差别。 包括jq和prototype的差别也没好好的了解过。
对方对asp.net mvc的要求也比较高,mvc我的了解也比较少。
特别是这位总监提到,他们对程序的性能有很高的要求。 这也是我特别想去了解的,如何去提高程序的性能 。
包括对方让我很好的描述 http传输的原理、为什么序列化能提高程序性能...等
我发现自己真的只停留在概念的表面!
完全杯具了!
不过我还是表现出了自己相应交流能力和学习能力。这位总监也很欣赏我挫败面前不低头的性格。他觉得我现在虽然实力不够,但愿意给我一次机会,让我好好的学习一下,觉得可以了在直接来找他,并把email留给了我。
我也很感激他愿意给我这么给机会,但我觉得自己更要好好的去丰富自己。 正如您常提到的一个好的程序员一定要有深度+广度。
我是86年出生的,也是个不小的人了,我知道现在厚着脸皮向您讨教学习方法是很不应该的。
但我现在一时间确实不知道该如何提高,我想您能不能从几个方面给我推荐几本书 或者 视频 之类的。
比如要学好asp.net mvc框架,我从什么书入门,然后看什么能提高。
包括如何深入了解http协议,.net序列化,如何提高程序的性能。
包括如何更深的去学习C#
我觉得我有一定的基础,我肯定能把这些学好,我一定行的。
我会在一年后再去找他,我不愿意认输。
很感谢周公能看完我这么多废话,希望能得到您的建议。以您这个过来人的经验,来建议我现在如何去一步一步的完善自己。
×××
我的答复如下:
×××:
你好!
非 常感谢你对我的信任,愿意把你在成长过程中的烦恼将给我听。我也很愿意分享一下我的观点和看法,只是在年龄上我比你多虚度了几年光阴,在开发上我比你多做 了几个不成功的项目及在面试上我比你多一些面试次数以及还有你所没有的面试别人的经历而已,所以我的经验和观点未必完全正确,仅供你参考。
首 先说一点我对你这封邮件的看法,在这封邮件里有几个错别字,还有一些地方词不达意,还有一些地方排版不是太好(周公注:上面的邮件已经经过周公排版),尽 管这不影响我阅读你的邮件,但是这会让我对你有一些小小的看法,比如你不够细心——尽管我可以猜想为你在上班之时给我书写邮件,慌乱之中会出现这种现象, 但是这不能成为你没有做好的理由。特别如果是在你的简历中出现这样的问题,可能第一眼就会被pass 掉。也许你会不以为然,会说这样或者那样的理由,但是这些理由在某种程度可能会看做借口或者做其它的联想,比如你说因为时间紧慌张所以出现了错别字,那么我会想如果把你招进来之后遇上项目紧的时候你是不是同样也会慌张因而出错呢?
ASP.NET初级程序员的现状
接着我谈谈目前ASP.NET 开发的现状,目前很多培训机构及一些出版社给初学者灌输的都是如何方便地使用 ASP.NET 服务器控件——显示数据记录使用数据绑定控件,对数据库操作使用数据源控件,这样就给一些初学者造成了一种假相——学好了 ASP.NET 服务器控件就等于学好了 ASP.NET ,甚至就等于学好了 .NET ;如果能熟练掌握这些控件的用法,能在数据绑定控件里面嵌套服务器控件那就等于精通了。所以经常在 .NET 里看到一些“ .NET 高手”在网上哀叹:“精通 .NET 开发居然找工作那么难,好不容易找到了个工作比民工薪水还低!”其实完全不是这样的,真正的 .NET 高手还是奇缺的,如果你知道你身边有这样的人请告诉我,我的很多猎头朋友让我向他们推荐呢。当然这种现象不是最近才出现的,至少在 2007 年我负责招聘的时候就注意到这个问题了,我当时就写了一篇博客《一才难求——也谈程序员素质问题》里记录了这个问题:
情 况之一:不会利用msdn。众所周知.net类库包含有几千个类,不可能去记住每一个类有哪些方法和属性,特别是在初次使用一些以前没有使用过的类时,查 看MSDN帮助应该是第一选择。在面试中发现很多人根本没有这一概念,有些根本不知道怎么用(在面试做题的时候,我一般都事先声明允许查MSDN)。
情况之二:不懂一些基本而且必须知道的知识。最离谱的一次,居然遇见一个不会将FLASH嵌入到aspx页面中的程序员(有HTML的可供参考)。有几次还遇见过需要Response输出一些HTML代码的情况,有的程序员居然不知道怎么写。
情况之三:基本概念不熟,比如一些程序员无法区分抽象类、接口之间的区别和关系。
情况之四:自视过高。有一个工作一年的程序在简历上写着“精通数据库设计、设计模式、系统分析和开发工具,对架构设计也有深入的研究”,看了这种话我开始是大吃一惊,后来跟他谈他“精通”的有关领域的话题,他基本没插几句话。
最 后,想给正在求职和即将要求职的各位程序员一点建议:抛却急功近利的想法,不管什么行业都注重经验的积累和沉淀,平时学习和工作的时候一定要多动手动脑, 通过自己的思考和实践才能加深和巩固印象。不要抱怨自己的工资不高,先问问自己的水平高不高,如果你的水平高的话,公司不敢不给你高工资,因为他不给别人 会给的,在这个浮躁的年代,招聘一个好程序员是非常不容易的。
.NET的历史渊源
做.NET 开发有几年时间了,我经历过从 .NET1.0 一直到 .NET4.0 的过程,所以对于它们的历史我可以简单说说。最早支持 .NET 开发的是 VS2002 ,所支持的版本是 .NET1.0 ,第二年就推出了 VS2003 ,所支持的是 .NET1.1 ,主要是修复了 .NET1.0 的一些重大 Bug ,此时 .NET 是向下兼容的,开发的 ASP.NET 的版本分别是 ASP.NET1.0 及 ASP.NET1.1 ;之后推出了 VS2005 ,它支持此的 .NET 版本是 .NET2.0 ,这个版本与以前版本相比主要是增加了对泛型、局部类和可空类型的支持等,注意 .NET2.0 对低版本不是完全兼容的;紧接其后推出的 VS2008 支持的 .NET 版本有 .NET2.0 、 .NET3.0 及 .NET3.5 ,与 .NET2.0 相比, NET3.0 及 .NET3.5 增加了 Windows Communication Foundation ( WCF) 、 Windows Workflow Foundation( 早先曾叫过 WWF ,不过现在改叫 WF 了)和 Windows Presentation Foundation ( WPF )组件,在语法功能上增加了 LINQ 和 Lambda 表达式等,使得编程大大地方便和提高了,基于 .NET2.0 、 .NET3.0 及 .NET3.5 开发的 ASP.NET 应用程序所使用的 ASP.NET 版本都是 ASP.NET2.0 ,在这个时候可以通过安装 VS2008SP1 的方式以内置支持 jQuery 和 MVC ,这个时候使用 .NET3.0 及 .NET3.5 是兼容 .NET2.0 的; 2010 年微软又推出了 VS2010 ,它支持开发基于 .NET2.0 、 .NET3.0 、 .NET3.5 及 NET4.0 ,不过 .NET4.0 不兼容它的低级版本,开发的 ASP.NET 应用的版本也是 ASP.NET4.0 ,在 .NET 中增加了很多新的特性,比如增加了 ADO.NET Entity Framework ,此时集成 jQuery 和 ASP.NET MVC2 。
关于经验
关于经验的积累跟项目有一定的关系,但并不是全部。对于ASP.NET 开发大部分可能会有这么一个过程:
首先是觉得服务器控件挺好用的,在开发中大量使用服务器控件;
经过一段时间的开发之后(也可能是听别人说),会发现服务器控件并不是想象中完美无缺,在VS2010 之前很多 ASP.NET 控件默认会启用 ViewState 来保存控件状态,这样在最终生成的 HTML 页面的源代码中生成了大段的隐藏域字段,影响了网页的传输速度,慢慢地我们会发现其实 ASP.NET 服务器控件最终到客户端时会被转换 HTML 代码,那么使用 HTML 服务器控件也是可以的,并且还省去了转换这个过程,所以在开发时尽量不处处使用服务器控件;
再经过一段时间之后,我们会发现有些复杂的效果与其去层层嵌套服务器控件,还不如直接将这部分特殊效果的HTML 代码输出,这样更方便快捷,然后我们也会想到有些操作其实用 JavaScript 也可以在客户端实现而不是必须要提交到服务器端才能处理,这样又提高了效率;
再过一阵子之后,我们会觉得SELECT * FROM Table 尽管什么时候都不会出错,但是并不是最高效的,在某些时候我们只 SELECT 要显示的字段,除此之外当数据库中的记录一多时每次都将数据库中的记录全部查出来再取出需要显示的部分不显示的数据被弃之不用很浪费资源,所以会想到使用分页查询每次只查询当前页所需要的数据;
再过一阵子之后我们又会觉得原来那种对数据库执行增删改查的操作的代码每页都有,非常不好维护,第一步分析之后会想到使用数据库通用类,再仔细分析之后可能就会发现三层架构的好处进而接受了三层架构这种思想;
再继续思考总结,我们又会发现其实在SQL 方面有很多名堂,比如存储过程、触发器、函数、分组函数、联合查询、 UNION 等,也就是有些结果可以直接在数据库里进行处理而不是将多次结果分别取出来在 C# 中处理,尽管可以实现同样的功能,但是在数据库中处理可能更加方便和直接。
当 然这些都还是初级程序员所面临到的一些问题,如果真想提高自己,可能会注意到更多问题。比如到了一定程度之后我们会接触到不同的数据库,我们要对比分析一 下这些数据库之间的异同点;我们还会注意到实现同一种效果会有不同的做法,我们要注意不同的做法之间差别——哪种做法效率高?哪种做法占用内存小?哪种做 法安全性高等等。比如做ASP.NET 开发,可以使用服务器控件、可以使用 HTML 客户端控件、可以采用 Response.Write() 的方法直接输出及模板替换法,你觉得它们之间有什么区别?同样存储数据, Cookie 、 Session 、 Application 及 Cache 都可以保存,它们之间又有什么差别(提示:可以从保存数据类型、范围、保存周期、安全性等方面考虑)?再比如非 ASP.NET 应用和 ASP.NET MVC 应用之间应用有什么区别?再比如 Convert.ToInt32() 、 int.Parse() 及 Int32.TryParse() 都是可以实现将字符串转换成 int 类型数值,它们之间在用法上有什么区别?有没有想过它们内部的实现呢?如果让你写一个类似于 Int32.TryParse() 的方法,你想过会怎么写吗? XML WebService 和 WCF 及 .Net Remoting 之间有可比性吗?在使用它们时该考虑哪些因素?参数化 SQL 语句和非参数化 SQL 有什么区别?在存储过程中执行的一定就是参数化 SQL 语句吗? string 和 String 之间是什么关系?什么叫字符串驻留池?什么叫数据库连接池,数据库连接池有什么用途?和诸如此类的问题有很多,实在是举不胜举了。
以 上的问题有多少使你感到难以回答?如果你能比较自信地回答上面的大部分问题,恭喜你已经具有中级程序员的开发经验了。我不知道辞海里有没有对“工作经验” 这个词下定义,根据我的理解我觉得程序员的工作经验包含了两个方面的经验:社会方面的经验和技术方面的经验。社会方面的经验包括了比如生活与工作产生了冲 突该怎么处理及与领导在某些问题上意见不一致该怎么处理等,这个如果不是应聘技术管理方面的岗位面试单位关注得比较少。技术方面的经验招聘单位会更看重一 些,通常所说的程序员的工作经验也主要是指技术经验。它至少包含了以下几个方面:
对于一些常见的编译错误和异常描述我们能迅速知道问题出在那里并及时解决;
对于一些可能会有多种方法实现的功能,我们应该如何根据当前项目的实际情况选择比较合适的方法;
对于一些容易影响性能的地方我们应该知道一些如何提高,如果存在多种解决办法,如何去评估那种办法的效率高;
对于一些容易发生安全性问题的地方我们应该知道如何去防范;
对于具体的应用如何去设计数据库或者去评估已经存在的数据库的设计好坏,如何在第三范式和字段冗余之间取舍;
如何在时间复杂度和空间复杂度之间取舍,知道如何用空间换时间(比如使用缓存就占用了内存但是换来了效率的提高,但是缓存并不是使用越多越好,此外对于数据库中索引字段也存在这样的问题);
对于常见的问题我们应该知道如何去处理;
对于从来没有遇见过的问题我们又该如何借鉴已有的经验来处理而不是束手无策。
要 解答以上问题,可能要求我们的知识面要相对广,在某些问题上要有一定的深度。实际上上面的这些问题已经脱离了语言本身了。在武侠小说中经常听到高手会说所 有的武功最终都是百川归海,在编程开发中我们经常会听到编程高手会说“语言只是一种实现手段,重要的是思想”,那么思想到底是什么呢?为什么有人要求在项 目中某个类只允许一个实例存在你就会想到单例模式?这就是经验,但是经验是什么呢?真的不好定义,尽管在上面我列出了经验的一些体现,但是那并不是全部, 我只能说“经验是一种很玄很玄的东西”。
如何积累经验
不 要晕,也不要倒,其实我们有很多办法增加自己的经验。围绕磨盘转了一辈子的骡子并不是一头有经验的骡子,将木棍捅到蚁窝中来捕食蚂蚁的熊也没有太多经验, 因为它们做那些事情不是出于被指使就是出于一种本能,很少去想是不是可以做得更好,而我们的祖先就做到了,所以今天我们成了世界的主宰。
说到这里,也