这是发在我的邮箱里面的一封信,这里做个统一回答。一家之言,欢迎拍砖哈。
(原信篇幅过长,请大家到原帖去看)
我的回答:
这位同学你好,从这封信看得出来你的心情还是很急迫的,你这种心情我完全能够理解。我把问题分几点说,尽量说细一点,希望能对你有所帮助。
首先,你说你是09年毕业的大学生,那么算下来,你应该上班才几个月而已,就这一点,你能在新的单位几个月时间就把工作拿上手,首先恭喜你,这说明你是真的很有实力,当年我转行游戏编程,用了差不多两年才真正想清楚程序设计的真意,我觉得你比我强。呵呵。
你说Java基本上都是做B/S数据库,觉得没有意思,其实这个我也很理解,不过,我觉得你可能不是很了解实际情况。这里我需要给你讲清楚,其实不仅仅是Java程序员,只要到企业中做应用开发,或多或少都和数据库沾点边。当年我用VC还写报表系统呢,你能说这不是数据库?
其实有个问题可能大家都没有关注到,至少,我到学生大本营半年,发现大家都没有讨论过。那就是,做什么最赚钱?无可否认,软件可以实现各方面应用,不过,就我的观察,在现实生活中,有两种软件最赚钱,一种是数据库,一种就是嵌入式底层的东东,嗯,随着互联网的发展,目前做网络程序也很赚钱。
其实原因很简单,就是因为软件的盗版问题。我想看到我这篇文章的每个人,或多或少都用过盗版软件,包括我自己,呵呵,咱们中国人穷啊,动辄几百上千的软件费用,咱们买不起的,所以电脑城的光盘市场才这么火爆。
但是,这带来了另外一个问题,就是当有一天,我们自己成为软件开发者的时候,才发现,盗版导致我们自己的收入降低,无法维系生活。这时候,恐怕再来大声疾呼,杜绝盗版,已经晚了,你说是不?
其实我们可能对市场不敏感,反正每个月发薪水,收入基本上旱涝保收,但是公司的老总们对这个很敏感,软件卖不出钱,公司就亏本,亏多了,就垮掉了,最终程序员还是没有收入。
因此,公司里面做软件,一般都做上面的软件,即数据库应用,嵌入式应用,控制类应用,网络服务应用较多。因为这几种应用,不容易被盗版,能卖到钱。通用性的应用,比如操作系统,比如很多工具软件,比如PC游戏,其实很难卖钱的。
数据库应用,一般数据库本身是使用成熟的商用系统,如MySQL,SQL Server,Oracle等,我们小公司拿来,再根据具体应用需求,做二次定制开发,这是一大类市场,其实这个市场的真正名字叫做“企业数据应用定制市场”。由于是定制的,自然没有通用性,也就不会有盗版了。
控制类,嵌入式类,很多都和具体硬件设备相关,换个硬件平台就不通用了,大家知道,中国的东东,要防盗版,最好和硬件相关,只要绑定硬件,软件一般不好到,以前出的防病毒卡,汉卡什么的,其实利用的就是这个市场规律。
服务应用呢,就更好说了,由于主要程序逻辑都在服务器端,基于B/S的模型,客户端连个软件都没有,服务器的管理自然比卖出去的软件好管理,不容易盗版。因此,这类企业也活得长,比如各个网站,各种网游什么的。所以我一直觉得,以后云计算发展起来后,很多软件可能会把零售制改为租用制,比如photoshop,大家买套软件几千,但一般人就是处理一下自家照片,自然不划算,因此盗版很多,但以后假如软件公司把它做成服务器版,大家把照片上传,处理,最后再存回来,这个过程每次租金1毛钱,每个人都花得起的话,我看以后就没那么多盗版了。另外,服务器应用其实大多数也是数据库应用。
所以,我首先要说,不管你是不是换工作,以后你恐怕会一直遇到数据库类的应用,不管你喜欢不喜欢,但这是社会的现实,你必须承认。你说对吧?
在这个共识下,我们再来看,其实我们会发现,三大主流应用中,只有嵌入式不适合Java,其他的数据库和服务器应用,其实Java比C和C++方便得多,因此,我建议你就在Java这条路上走下去,不一定非要转C和C++。本来你的强项就是Java,而且这也是主流的可以卖钱的市场,为啥不坚持呢?
从另外一个角度说,我也认为你应该坚持,你毕竟毕业不到半年,对社会,对公司,对本职工作其实了解并不深入,你认为Java就那么几个设计模式,没有挑战性,这个我能理解,但是,我觉得你说的不全面。起码我做程序做了这么多年,到底有多少种设计模式,我也说不清楚,我相信很多人都说不清楚。需要具体应用具体分析。
我不是Java程序员,不过我觉得,如果要做一个合格的程序员,首先不应该是程序设计的大师,而应该是理解客户需求,并迅速拿出解决方案的专家,这个,不管用什么语言,不管在哪里工作,都是必须的,同时,这也需要很长时间的积累。
准确的讲,我认为,一个人不在一门语言,一种业务领域努力3年、5年乃至10年,是很难成为专家的。因此,我建议你完全没有必要这山望着那山高,轻易就决定跳槽,建议你就这个环境,先锻炼自己,我这里放句话,你可以试着验证一下,两三年以后,你再看Java语言和数据库开发,都还是会找到自己不会,值得学习和钻研的东西的。因为最起码,客户的需求是千变万化,永无止境的。
当然,话分两说,如果你真的喜欢C,很想做嵌入式应用,就是不想做Java,那也无可厚非,因为毕竟每个人都有选择的权利。
不过,我仍然不建议你辞职回家学习。我以前有句话,大学毕业,才是学习的开始,不过,这个大学毕业后的学习,和学校中的学习,有很大差别,突出的几点:没有老师,没有教材,都是自己主动学,针对自己的需求来学习,学技巧多,学原理少,并且一般都是干中学,而不是学完了再干,我总结就是“用以致学”,而不是“学以致用”,这是我总结的学习经验。
同时,毕业了,总不好意思再向家里面父母要钱,总得自己赚钱养活自己。你说是吧?你说辞职半年,专心学习,那你没有收入吃啥?还不是吃父母的?这样不是很好。
C语言没有那么神圣的,也没有太高的门槛的,不要想太复杂了。另外,指针,内存什么的,学习C语言确实能接触到,但是,我还是要说,C语言并不是因为有了指针和内存的直接访问,才牛叉,C语言是因为大量的程序员用它解决了很多具体应用,才牛叉的。请你注意不要学偏了,不要为学指针而学指针。指针就是指针,仅仅是个访问工具而已,不是用来显得很酷的,需要了才用它。
Java语言用个数组,其实也能模拟指针的大部分功能的。其实我作为C程序员,我们平时工作时对指针是很谨慎的,能不用都不用,尽量用引用来代替,为啥,因为危险,容易出错。
数据结构,计算机组成原理,算法语言,编译原理,嗯,还有个图论,这几门应该算最经典的计算机理论了,但是,也没那么神秘的,书店里面有,自己没事买几本回来看看就好了,生活是没有考试的,不需要你必须考够100分才能找到工作,了解,理解就好了,背书是背不出好程序员的。你说对吧?
其实这几门,不用C和C++语言,用Java语言一样可以学习的。嗯,编译原理可能够呛,需要理解一点C。
另外,我再给你透露一点点,其实真正实际应用中,我们对于上述基础知识用得很少,用得最多的,其实就是数据结构里面的队列了,其他,包括栈都很少用,C程序员也不是每天都从底层,从0做起的,还是有很多工具套用的。这和Java语言从框架开发是一个道理。
反而有一门课程建议你好好学,就是概率和统计学,这门知识是我现在应用最多的,很多时候,我们评估软件系统性能,瓶颈优化,都是在用这个学问。程序员做久了,可能大多数时候都是和这个在打交道,建议买本好好看。
总结一下吧,建议你目前暂时不要辞职,既然选择了Java和数据库应用开发,选择了B/S模型,你耐心做3年再看,也许3年后,你自己的想法就变了。
C可以学,你说的课程都可以学,不过,不要辞职专门学,先赚钱养活自己,再利用时间学习,你这么大的决心,每天晚上就不要看电视了,那你每天晚上,19:00~24:00,至少有5个小时来学习,利用好了,我敢说比你在大学里面效率高。
看书学习不是什么神秘,神圣的事情的,也不需要什么斋戒沐浴,念几天经才能学习,我觉得就和我们吃饭喝水一样,随时都可以学的,找几本书,就在床头放着,每天晚上看看,几个月也就看完了,又有多难嘛?
关键是,养成习惯。
你说对不?呵呵,先说到这里,有问题再问哈。
最后补充一点,如果学习C,并且有一定基础的话,等我书出来看看吧,里面的跨平台开发工程库,可以帮助你迅速掌握嵌入式底层的一些技巧。不过,要有基础哈,一点不会C看不明白的。
(该位同学继续来信咨询并表示了决心,原信过长,这里不转贴了,请大家到原帖来看吧)
我的回复:
这位同学你好,我昨天其实已经说明了我的一个观点,虽然我建议你继续努力学习Java,不过,每个人都有选择的自由,因此,如果你还是坚持要学习C的话,我也不反对。
你在两封信里面,都强调你原来是个差生,但最后半年知道发奋学习,最终过五关斩六将,成功拿到offer,超过了很多同学,也让老师的眼镜掉了一地,呵呵,我真心恭喜你,也很佩服你。
其实我以前有笔记说过,人要发奋,什么时候都不晚,苏东坡的爸爸是这样,小时候我们学的《周处除三害》也是将这个道理的。你能把计算机里面200G的游戏和电影删掉,换成学习资料,嗯,了不起,比我强。
不过,如果我们要讨论C的学习路径,恐怕要让你失望了。因为C和Java语言并不一样。并没有前人规划好的必然成功之路。
Java语言由于面向应用面相对狭窄,框架模板众多,最重要的,其主要工作方向比较确定,就是做基于网络的跨平台数据应用为主,因此,其发展方向很容易确定,学习路线也比较好规划。
但C显然不是这样,C应用面太广,可以说,汇编能做的事情,C就能做,甚至做得更好,也就是说,我们能想出来的计算机软件应用,其实都可以由C来实现,仅仅是成本高低而已。
而不同的应用,除了计算机软件编程知识之外,还需要很多应用相关的知识,这就造成了C程序员往往也需要成为自己应用方向上的半个专家,这就比较麻烦了,这么多的应用方向,写游戏的知识储备,和写驱动显然不一样,与写操作系统和编译器的方向又显然不一样,因此,很难说一个C程序员需要掌握哪些知识,才够用。
以我自己为例子,我做程序差不多快20年了,做C也超过15年,做过游戏,工业控制,电子教育,网络传输等各种软件,我总结自己的知识储备,也仅仅觉得自己在数据传输方面有一点心得,并且对于C和C++语言怎么实现0Bug程序设计,有点经验而已,真不敢说自己什么都会。
另外,C语言之所以难学,并不是说它自己多难,真正的问题在于,C语言偏底层,只要我们一做应用程序,或多或少都需要调用很多操作系统相关的api来完成工作,Windows下,如果我们不懂Win32API,则很难写出合用的代码,C语言玩得再熟都不行,Linux下对于各种系统和应用级api,也需要不断查询man,否则根本写不下去。所以,要想成为C程序员,至少要学习操作系统,通常,至少应该把Windows和Linux常见的api学一遍。MFC是Win32API的C++框架表示,最好也学一点。
其实这已经带出另外一个话题,现代开发,C和C++一般不分,C++到了函数内部,其实是C,而C呢,有很多特性写程序不够方便,也需要使用很多C++的特性,如默认参数,如引用等等。所以,学习C,最好和C++套着学,都看看。呵呵,这已经是两门语言了。
还有一个问题,不管是C还是C++,总是各个具体的操作系统上开发,Windows和Linux有差异性,很多库函数,常量定义都不一样,因此,C和C++一般说来,很难做到程序通用,需要使用大量的编译宏,这需要了解语言之外的东西,即编译器的很多特性,不过,很可惜,关于编译器特性,目前的资料很少,我很多都是摸索的。
另外,现代的操作系统,都是多任务操作系统,多任务开发是个难点,这个多任务计算其实就是并行计算了,必须对进程,子进程,线程有很清楚的认识,对于时间片有清醒的认识,对于锁的使用,锁的作用域,去锁优化要很熟悉。但是,也很可惜,目前市面上的书籍,讲语言的就讲语言,讲操作系统的就讲操作系统,对于这个多任务开发这块,同时需要结合语言和操作系统两方面知识的,几乎没有,需要自己摸索。其实我写《0 Bug ---- C/C++商用工程之道》,有很大一部分目的,就是希望填补这个空缺的。即从语言和操作系统中,抽象出来,站在更高的角度,从较为宏观的立场探讨并行计算程序的开发之道。所以我说如果你要学C,等我书出来最好看看。
嗯,还有一个很重要的问题,C语言的基本库相对薄弱,很多近年发展的高级语言,对于哈希,List,队列,栈,树等常见数据结构都提供标准库函数,或者库模块来支持,但C一般是没有的,偏偏实际应用开发还经常用到,得自己找开源,或者程序员自己写,这也会耽误程序员很大一部分精力。
这里就出现了C语言一个不好不坏的特性,或者说既好也坏,C语言没提供这些工具,程序员自己写,很麻烦,但是,由于是自己写的,自己掌握所有底层代码,因此,优化变得很容易,一个队列,我随手加个队尾指针做加速因子,可以规避大量的递归操作,效率提升百倍甚至千倍以上,这在C里面就是加几行代码而已,但是对于Java等语言,由于底层库是厂商提供,甚至根本就不是本语言开发的(很多高级语言底层库其实是C和C++写的),程序员一般没有修改能力,有时候,遇到性能瓶颈,大家就只有干看着,没有任何办法。因此,同样的应用,C语言可能一台服务器就够,但是Java语言呢,可能需要3~5台,就是因为这些语言做的太完善,而太完善的东西,一般不好做优化,性能就不及经过专项优化的C代码。
就是因为这个原因,在很多嵌入式等小终端场合,由于CPU计算能力有限,需要使用C来做优化,而不能使用Java等高级脚本语言,否则程序跑不过乌龟。
另外,现代的数据应用,出于优化起见,一般趋于功能细分的设计模型。比如一个数据库应用,存储模块专门负责高速出库和入库,中间甚至添加cache机制作专业的优化,而业务模块则强调设计一套嵌入式脚本语言做二次开发,保持最大的业务开发灵活性。其实Java,PHP,很多都是这种模型,MySQL底层模块实现高速存储,上层则使用apache和PHP、Java等语言,灵活二次开发具体应用。
但是,C由于一般都是编译执行,不是解释执行,一般很难做到这么大的灵活度,不能用户仅仅加个字段,就跑过去把整个服务器重新改写编译一遍,这样维护成本太高了。因此,C程序员的解决方案,一般是自己实现底层的高速数据应用,再自己写个脚本语言的解释器,提供给用户做二次开发。
你发现什么没有,其实C程序员如果做企业数据应用,一般需要具有编译原理的知识,我们一方面要实现用户的业务,还需要写一套Java这类脚本语言给用户做二次开发用,说白了,就是我们自己实现一套lamp体系,呵呵,这不是又费马达又费电嘛,因此,我前文说,做数据库应用,最好直接用Java,直接用C,成本太高,而且不容易满足用户需求。
说到这里,你又发现什么没有?C语言之所以难学,并不是C本身难学,而是如果要成为一个C程序员达到实用级的地步,需要掌握很多方面的知识,这些知识,书上可能有,也可能没有,没有的,就要靠钻研,靠实战,靠自己去想通,因此,很难通过K书成为C程序高手的。建议你学习时,关注C这个特点。
不过好在你强调做游戏和嵌入式两种,这两种呢,我可以根据经验讲一点:
如果从事游戏的话,很多时候是和图形打交道,目前的游戏,趋向是大型化的视频图形游戏(包括大型网络游戏、电视游戏机的游戏)和小型化的终端游戏(手机类、PDA游戏),这两种比较好卖,至于中型规模的PC游戏,由于盗版太严重,已经很少人做了。仅仅是一些游戏公司为了宣传自己,会出一些经典的大作。
嗯,硬件厂商为了宣传自己的新板卡,如新的图形显示卡,会拿出钱来,请游戏公司做一些针对该型板卡特定优化过的游戏,以刺激广大用户对硬件升级换代,这也是一条财路,很多游戏,在面市之前,就已经从硬件厂商获得了足够的利润,并不需要从零售市场获取利润。我们在电脑市场看到,几乎每出现一款游戏大作,就带来一次显卡,甚至PC机硬件的升级换代热潮,其实背后就是这个故事。
不过呢,游戏引擎我还是建议你最好不要去做,因为做这个成本太高了,很少有公司去做,而这些公司,一般都是欧美公司,对人员要求很高,轻易不会招收亚洲国家的程序员,因此,学这个好比屠龙之技,看起来是很酷,但是实际上工作机会很少,甚至不比中彩票来得高。
另外,做游戏引擎不好玩的,因为现在也都细分了,做引擎的公司一般自己不出游戏,最多出点Demo,他们就是提供高性能引擎,而不是好玩的游戏,而游戏公司,则是购买引擎,然后开发具体的游戏内容。比如Quake和虚幻的引擎,就很多家游戏公司买去做自己的游戏。其实很多游戏引擎,目前也提供脚本语言,即里面用C实现了另外一套语言。
游戏公司其实主要是美工建模,绘图,企划编故事情节,程序员反而很少,更多地是使用脚本语言,在引擎基础上做二次开发而已。因为游戏公司就是做好玩的游戏,至于具体用什么技术,其实他并不是很关心。说不定,如果你哪天进个游戏公司,会发现自己又见到Java语言这个熟人,呵呵,那个时侯会不会有欲哭无泪的感觉?
其实这也是社会分工的不同,好的引擎程序员,更多的是个数学家,强调逻辑思维,你让他去写个美少女梦工厂,如何抓住少女的心,还不如杀了他,呵呵。
而做嵌入式系统,其实也有诀窍。嵌入式系统,目前我们看到的手机应用仅仅是很小很小的一类,更多地,嵌入式系统是应用到工业控制领域,从大型机械设备的控制,飞机、汽车轮船的控制系统,甚至到十字路口一个红绿灯,里面都是嵌入式系统。
目前有个现象,嵌入式好赚钱,很多学软件的同学都想找嵌入式工作,但是,毕竟在这个领域里面,给手机做游戏的就那么几家公司,不可能吞下所有的人才,更多的是需要自动化控制人才,因此,这类软件转嵌入式的人,进去一般都有点缚手缚脚的感觉,总觉得知识上欠一点,又不好补。
其实,嵌入式应该是最简单的,比如说驱动,就很多硬件厂商要人,而驱动其实就是做一套打口读口的api,很简单,最多做的时候注意点,别用太复杂的算法,保证计算速度而已。
但是你注意到没有,嵌入式其实主要是和硬件打交道,硬件知识必不可少,至少,计算机组成原理,数字电路,模拟电路要很熟,最起码,你要知道开关量和模拟量,要知道集成电路的选通信号和真值表,对于地址表的编址要很敏感,对于常用的集成电路块的特性,比如8235等,要比较了解。否则,是写不好嵌入式程序的。
因此,我以前有笔记说,嵌入式开发,很多时候软硬件不分,我见过的很多嵌入式工程师,其实也能自己画一些简单的电路板,至少,他在设计时,知道哪些功能硬件来做更合适,而不是一味的走软件路子。
不过,嵌入式学习要钱,这是肯定的,最起码,你自己手边要有个基本的嵌入式平台,不过好在这个并不贵,一个arm9的开发板,目前也就500多元,淘宝上就有卖的,买块回来自己做练习,应该不难。
如果要我给你职业路线建议,我还真想建议你就走这条路子,原因很简单,工作好找,进去之后的门槛并不高。你花点时间,自己钻一下数字电路等前面说的几本书,对于底层的汇编看看,主要看看arm的和51系列的就好了,也不用看太精,嵌入式程序大段大段的都还是C,仅仅部分端口动作,为了协调时序,采用用到汇编,而且,用得最多的还是NOP指令,就是强制CPU延时,这个很容易的。
最关键的是,嵌入式设备在很多工业设备制造公司都有用到,他们也需要大量的人才,并且,我们都知道,公司里面,普遍学历最高,年龄最低,门槛也最高的就是IT软件企业,这些工矿制造企业反而门槛比较低,进去之后,老板也比较看重人才,因为制造业的产品一般立竿见影,开发一套设备半年就开卖,不像软件,一般要开发到3.0版才有市场,呵呵,老板看得到钱,自然也比较看重赚钱的人的。
虽然你是软件人员,上述硬件知识没有学过,不过就我学习的经验,其实反而门槛还低,甚至比学个Java的框架来得还容易,建议你可以考虑从这条路上走。
嗯,先说到这里吧。有问题继续探讨。
最后我还是要劝你一点,生活不是PK,生活也不是孤注一掷,没必要什么时候都把自己逼到绝境,想成功其实很容易,只要制定一个目标,一个计划,然后按部就班走就好了,不需要找锥子扎自己屁股的,那是自残,呵呵。
自然一点,看开一点,少给自己太大压力,看书累了,看看电视也没啥,出去走走也没啥,没事的时候,眼睛从计算机屏幕上转一下,看看身边有没有合适的女孩,谈谈朋友也不错,如果那个错过了,才是一辈子的遗憾。
成功的道路,应该是很快乐的,如果都是眼泪和汗水,即使做到百万富翁,又有什么意思?
你说呢?
学生评论:
成功学院Gwolf-Team sky_water(Net爱好者):
很喜欢这句话:
C不是因为直接操作内存才牛才,是因为他解决了好多问题才牛叉
我想任何语言都是
犹如在战场上能杀敌的兵才是好兵
广东工业大学 cch(Java学生) :
受教了,“关键是,养成习惯”,能举的我都举起来赞成
孙建(C/C++学生) :
肖老师出品,一定要看,自己在也C/C++语言中迷茫,基础已经看完,就是不知道后面怎么走,这下,又知道应该做什么了!了解WIN32API函数,呵呵,还有别的,
四川大学锦江学院黄启银(Java学生) :
肖老师 我真的很感谢你 你让我明白了我以前不知道学模电 到底以后能干什么呢 现在我应该好好学习模电了哦
合肥师范学院董海(C/C++学生) 2009-10-19 17:50
每个字的读 我对以后的方向一直很迷惑 看来我有方向了
湖南大学冯本明(Java学生) 2009-10-23 21:56
旁边的师兄还在说他们去面试公司10家只有一家找java程序员,看了你的讲解后,我觉得还是要坚持自己的想法,无论什么行业,做精了,都是专家,牛人。
福建工程学院软件学院四维(Java学生) 2009-11-05 11:02
一字一句的看完了,心情很不一样!
相比之下我是刚踏入大学一年的学生,路还很长,却没有动力和毅力!
谢谢你的分享
江西财经彭文忠(C/C++学生) 2009-11-21 17:17
第一:真很佩服这个学生,他的经历让我知道要好好珍惜大学这剩下的三年啊
大一我也混了一年,还好觉悟的还早现在还有信心学好;
第二:肖老师的回复让我学到了很多东西啊,让我明白原来要学好C++就必须学
好那些我薄弱的课;同时也让我更加清楚了C/C++是一门怎样的语言,处于什么
地位;谢谢肖老师