C#、C++、Java、Python 等语言选择

作者:刘哲奇

链接:https://www.zhihu.com/question/298323023/answer/510597050

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

首先排除Python,光动态语言一个理由,就已经万劫不复了。无论有多少所谓优势,在这一个缺点面前,都显得微不足道。

动态语言是为了七八十年代的古董计算机而设计的,那个年代的电脑操作系统还不到1MB,比如MS-Dos,Unix,Amiga等,所以绝大多数动态语言都是古董语言。Python在其中算是相对“年轻”的,但也是30年前的技术了。

除了Lua,Julia等极少数90后之外,绝大多数动态语言都是无法操纵线程的。因为那个年代的CPU是单核的,操作系统不仅是单线程的,有些系统甚至是单进程的。

虽然后来很多动态语言加入了协程,但其实还是只能操纵一个线程的,连“治标”的问题都没能完全解决,更别说“治本”了。很多初学者以为这是“快”与“慢”的问题,会随着硬件性能提升而逐渐改善,然而恰恰相反,硬件性能越提升,与动态语言越脱节。因为这些动态语言能有效发挥的CPU性能,始终停留在单线程的时代。
当时的主要储存介质是软盘,就是那种正方形的塑料小卡片,最大容量只有1.44MB,为了能够装在软盘里面,所有动态语言的语句都特别简短。用今天Python圈儿里的话说,当时几乎所有的编程语言,全都非常“优雅”。

后来硬盘容量变大,windows诞生,计算机完全进入图形化时代,程序变得越来越庞大,一个程序从原本的几KB,瞬间增大到几十几百MB,乃至GB。
从此,为了编写kb级项目而设计出来的动态语言,越来越难以胜任软件的编写任务,被视为落后技术,除了JS之外,几乎所有主要工作都被静态语言取代,一大半动态语言从此灭绝了,活下来的动态语言则只用来编写脚本,才有了“工程语言”和”脚本语言”一说。

动态语言只适合写非常小的东西,项目越小,写起来就越爽,越大就越抓狂,且非常难以维护。网上各种不到一百行代码的“小项目”来证明Python如何如何优雅,而你去工作之后会发现,这样的“小项目”今天只存在于三个地方。

  1. 培训机构的教学计划中
  2. 各种教程的案例中
  3. 粉丝们相互洗脑的言论中

实际生产中,你见到的“小项目”代码行数都是以万为单位的,如果对Python代码进行封装的话,维护难度几乎是在挑战人类耐性的极限,无时无刻不抓狂,当然,也确实有个别使用Python写成的“大项目”,但无一例外,都是靠大量注释硬磨出来的。注释的行数比代码的行数要多得多。这时候就已经不是“写代码加注释”,而是“写注释加代码”了,编写体验就像是在写一部”超长篇中文说明书,其中掺杂着少量代码”,但你不把“长篇说明书”看完,这些曾经由自己亲手写出的“少量代码”,就死活看不懂。

而且写完代码,确定不需要修改之后,还有一步工作要做,就是把那些浩如烟海的注释,删掉绝大部分。否则注释实在太多,会垫高运行成本,一个耗费大量精力编写的项目,刚写完时超过1GB,注释删光之后,还剩100多MB,内心里数不清的草泥马。

另外三个都是不错的选择,它们都是静态语言。若想开发一个中型以上的项目,而且希望可以有效维护的话。使用静态语言来开发,才能让你避免抓狂。

就像铁锹与挖掘机,如果给宠物挖个厕所,挖掘机显得既难学又难用,一学就是两年起步,考一堆资格证,还各种不熟练。铁锹简直太棒了,分分钟秒懂,抡起来就开挖。挖掘机还没热好车,用铁锹三五下就挖好了。铁锹显得各方面都很完美,挖掘机简直一无是处。但如果你想挖一座水坝,并指望长期靠这门手艺混饭吃,还是
先去中国山东找蓝翔,把“既难学又难用的挖掘机”学好再说吧。

当然,“不适合”与“不能”是两回事。毕竟仅凭双手都能磊出万里长城,用铁锹又怎会挖不出水坝?只要有愚公移山的精神,动态语言当然也能写出大型程序,只要玩命加注释就可以了。可问题就在于,仅为了“简单易学”这么个优点,而在漫长的职业生涯中反复不停的“移山”,值吗?

既然说Python,当然要提一下人工智能,这确实是Python最大的存在价值。在熟练掌握一门静态语言的前提下,确实可以抽时间学一下。但如果你连一门静态语言都还没掌握,只学了学Python便指望可以去搞人工智能开发,那真是想太多了,因为现实情况是一环扣一环的。人工智能水坝很高端,但你得先把水坝挖出来才行,否则用卷积神经网络能存水嘛?人工智能就像一件太空服,确实是高级货,但要发展航天,需要优先考虑的问题,却是如何造出一枚运载火箭?如何造出飞船?如何培养宇航员?当一切条件完备之后,才适合考虑太空服的问题,否则就是本末倒置。若连宇航员都还没有,太空服给谁穿?没有飞船,又何来宇航员?没有运载火箭,飞船又怎么上天?

既然说完了“为何要用挖掘机,而排除铁锹”的问题,下面就该说说“挖掘机技术哪家强”了。

三门静态语言的语法是高度相似的,尤其是Java和C#,简直是太像了,学会其中一门,另一门你就会了八九成(只论语法部分)。完全可以在几天之内,从一门语言过渡到另外一门语言。所以若想同时学会三门语言,其实一点都不难,但我不建议这样做,因为这基本是在浪费时间。

因为“学会语言”和“胜任工作”之间,有着一道巨大的鸿沟。几乎没有多少回头路可以走。比如我一开始是用Java做web开发的,由于工作需要,我需要学会“用C#做游戏”。凭借Java的底子,我只用了两三天的时间,就学会了C#语言。之后我用了一个星期左右的时间,学会了用C#做web开发。可是,当我决定使用C#转向游戏开发的时候,我花费了两年的时间学习,才勉强做出一个很小的项目。

用Java做Web开发,转换到用C#做web开发,就像从右手写字,转换为左手写字。并没有新的知识要学,仅仅是改变了握笔的习惯。虽然很容易,但却是在浪费时间。因为若要写字,只用一只手就够了。

之后,我试着学习用C#做游戏,就像从写字,转换到画画。握笔的习惯没有变,但所学的知识却完全不同了。所以即便我用了两年,但时间并没有丝毫浪费,因为我每天都在学习“之前不懂的知识”。

所以选择语言的关键,并不在于语言本身,而在于你要先想清楚,自己准备从事哪个行业。换一门语言非常容易。而换一个行业,就不是那么容易了。

在这三门静态语言当中,Java的用户数量一定是最多的,岗位数量也是最多的,但竞争压力也是最大的。因为Java的就业岗位,几乎全都集中在互联网行业,主要就是用ssh做web开发,安卓项目也有一些,但非常少,基本可以忽略。好的方面是,在互联网行业是最大主流,只要不挑肥拣瘦,找工作不是问题,而且在很长一段时间内,这种情况都应该不会有太大变化。坏的方面是,严重依赖互联网行业,只要选了Java,就必须一门心思做网站,因为Java在其他行业的岗位数接近于零。互联网高速增长,Java的雪球也就越滚越大。但如果哪天互联网行业不行了,Java就要做好陪葬的准备了,转型到其他行业的可能性微乎其微。这也是我转而去学C#的原因,根本目的就是为了在“编程”和“做网站”之间实现解耦。让“编程”可以做到更多的事情,否则你如何证明自己是个程序员,而不是个“网站制作员”?Java的亲爹“日公司”还活着的时候,个人是个铁杆Java粉,毕业后就找了份ssh增删查改的工作,一干就是七八年,但后来Java被甲骨文这个拿数据库当幌子,冒充IT公司的律师事务所收购之后,就开始变得不思进取了。除了整天上法院,在法律战方面大显神威之外,就只能蹭互联网的热度保持增长。这么多年来,始终无法在互联网之外的领域,拓展出哪怕一丁点儿用途。Java是我使用时间最长的语言,我从高中时代就开始学习它了,还专门因为它,才决定报考计算机专业。我原以为自己会写一辈子Java。可离开它之后,我却开始反问自己”当初为何没有早点离开?”。

C#是我的新欢,我实在特别喜欢它,至少目前是这样的。最重要的原因是,它能做的工作比Java多很多,PC设备集成,游戏开发,ios和安卓开发,串口设备通信,gis,工业控制,ao与erp系统,以及web开发全能做,而且学习效率和开发效率都很高。如果希望用最小的学习成本,获得最大的技术回报,它一定就是最佳选择。由于曾经不跨平台,错失了互联网崛起的时机,所以工作岗位并不像Java那样,全都集中在互联网行业,而是分布在各行各业。缺点是岗位太分散,岗位其实非常多,只比Java略少一些,但分布到各行各业之后,就显得没什么存在感了,在每个行业都不是老大,尤其在互联网行业非常弱势,也许连Java的零头都不到。C#的名字也不好,总让人联想到C++,以为它是门很古老的语言,其实C#是个00后,论辈分和Go语言差不多,尚处于“小屁孩”阶段,岗位数量能有如此规模,其实已经很了不起了。优点是,万金油,哪个行业都能干,又不依赖其中任何一个行业。如果哪天互联网行业不行了,很容易转型到各种行业。另外在游戏开发方面是主流,Unity,寒霜3,CE5等众多游戏引擎,均使用C#开发游戏。近几年在互联网方面的改进也还不错,有了.Net Core,终于可以跨平台了。优点是性能非常棒,是常见的后端框架中速度最快的,具体可参照TechEmpower的性能测试。缺点是.NetCore出来的太晚了,尽管有技术优势,但市场已经被Java占的稳稳的了,所以短期内Java必然还是唯一的主流。不过对我来说无所谓,能做网站的语言多如狗。“啥都能干”才是我选C#的理由。我想我可能会写一辈子C#。。。。。吧?

C++的牛逼之处,就是跑的特别快,而且理论上能做的事情比C#更多。尴尬之处就是无论做什么,都不能只会写C++,还需要一堆专业知识配合使用,语言层面和应用层面,得分开学。比如市面上C++的工作,大部分要和各种设备打交道。除了会写代码之外,还要懂电子电路,电气电磁,仪器仪表之类的知识。我大学的同学们,学生时代大部分都倾向于C++,学霸们专注ogre,次优生擅长opencv,学渣们也多少会点MFC和QT,结果一找工作,无论学霸还是学渣,全都跪了。要么是变压器厂的设备开发岗位,要么是蓄电池厂的技术研发部门,甚至还有造直升机的军工企业,全都要求懂设备。难得有个金蝶软件公司,招聘财务软件开发的工作,不要求懂设备,但却要求数学能力,需要会微积分。十几号同学排着队去了,结果人家当下招了两个,几天之后又辞退了一个,最后只留了一个。剩下的同学几乎全都改行了,有的干了销售,有的开了饭馆。。。本人没走这个路子,再多的也就不敢乱说了。

我个人建议:

想长期在互联网行业混下去,且没有中途跳船的可能,选Java,前期重点放在MVC模式的理解和数据库增删查改,中期重点放在服务器负载均衡与CND分流加速,后期侧重数据库优化。

想创造更多的可能性,选C#,重点放在.Net Core(跨平台后端开发)和Unity3D(VR,AR,游戏开发),并根据自身行业,选择关注Azure(云计算),WPF(桌面软件开发),Blazor(Web前端框架),ML.Net(人工智能框架),Focas(工业机器人编程),MasterCAM(数控机床控制),Xamarin(安卓与IOS跨平台开发)等技术的发展情况与细节。

如果你是学霸,有电气,机电等专业的知识背景,并有活到老,学到老的决心,学C++。

至于Python,最好的出路是搞培训,也可以去做一些运维,测试之类的打杂工作。当程序员的话,在一线城市是没什么希望了,下乡试试吧。运气好的话,遇到个煤老板,用Django忽悠忽悠,混个技术主管也是可能的。至于Flask,就相当于Java的HttpClient或者http://Asp.Net的一般处理程序,除了搞培训,实在是百无一用。


作者:孙策

链接:https://www.zhihu.com/question/298323023/answer/523720835

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

第一次正儿八经在知乎回答,居然这么多赞,看来知乎上IT男很多啊。谢谢大家!不知道能不能破千,要是破千的话,可以考虑写点技术的干货。
——————————————以下是原答。
作为一个20年的老程序员来回答一下。

1998毕业,现在自己做一家IT公司,依然喜欢写代码。

工作这么多年,正式项目用过的语言有: Pascal/Delphi,dBase/FoxBase,FoxPro,VB,VBScript,JavaScript,COBOL,C/C++,Lua,Java,C#,各种数据库的SQL。

最早学的是Pascal,大学里面学数据结构用的,毕业以后用delphi写了一个小项目,然后再也没有用过。

dBase/FoxBase也是学校里面学数据库的时候教的,然后毕业以后用的是FoxPro,也是做了一个小项目,后面基本就没用了。

VB/VBScript作为主力语言,从1998年用到2002年,对,那时候做ASP。也用VB写过还算有规模的EXE的项目。至今书橱里面那本《VB5金典》依然保佑一席之地。VB做快速开发真的很好用。然而http://VB.Net就压根没看过。那已经不是VB了。

因为Web开发基本上没有断过,JavaScript一直陪我到现在。
COBOL是原来在对日外包公司工作的时候,接了日本一个野村证券的项目,居然是COBOL,然后,作为新技术研发部的负责人,当仁不让上了。边学边做项目,做完就扔了。

C是从开始编程就学的,断断续续用一点点,2003年做银行项目的时候,用IBM小型机,Tuxedo中间件,然后只能用C/C++语言编程(那个时候银行还不怎么接受Java)。然后自己开始创业,做游戏,用OpenGL做了一个游戏引擎,跨平台的那种,一次编写,Windows、Android、iOS都能跑。C++写的。中间尝试了一下Lua,写了两个小游戏,觉得对程序的掌控能力还是比C差远了,就放弃了。

最后就是Java和C#这对双子星,是用的时间最长,做过项目最多的。C#是从2001年开始,beta版本开始学的。记得第一个项目是2002年6、7月的样子吧,那时候公司接了一个比较大的Web项目,本来是准备用ASP做的,结果那时候我正好在学C#,然后看了一下说是10月份会发布正式版(时间大概是那样吧,年数长了,记忆有点模糊),然后仗着自己是项目负责人,外加老板不懂技术,就擅自决定用C#/http://ASP.Net来做。项目做完大概是10月份,在项目上线的前几天,微软发了正式版ASP.Net1.0,项目有惊无险的上线了。现在想想有点作死的感觉。如果微软把.Net正式版的发布时间往后推一个月,很难想象老板会拿我怎么样。

Java差不多跟C#同时学的,然后一直做啊做,从EJB做到SSH,再到Android。那时候年轻,学习的精力旺盛,然后觉得C#和Java似乎差的不是太多。

PHP看过,没用过。Python看过,没用过。还有Ruby,看过,没用过。我说看过的意思大概就是写过Hello World,但是没有拿来做过项目。

我是真的喜欢写程序,所以有什么新奇的东西,都喜欢拿来跑一跑。

然后说说对编程的看法。

首先,我认为,语言没有高下之分,只有应用场景之分。作为一个技术决策者,拿到任何一个项目,首先第一个考虑的,不是怎么做,而是用什么做。如果你拿到的是一个Web项目,我认为,在很多情况下,JSP、PHP、http://ASP.Net甚至Node.js基本上都是等价的,应该都能够很好的完成项目的开发,选择什么技术开发,看自己所拥有的资源禀赋和具体情况。如果手下一帮弟兄都是搞Java的,当然JSP啊,如果手下小弟都是做C#,当然http://ASP.Net啊。当然,项目有特殊要求的除外,比如,如果甲方是银行,那估计就没法用http://ASP.Net了,如果是有客户端的项目,当然C#+WinForm啊,如果是做安卓,当然Java啊。
其次,作为一个好的程序员,应该至少会三种以上语言,这样你能够充分接受不同语言的风格,更关键的是你会去关注不同技术社区的讨论,开阔眼界,对编程的本质会有更深刻的体会,然后你会觉得,看任何语言都是差不多的。我经常对公司的技术人员讲,要用Java的编程思想来写C#的代码。这是不同技术社区的风格体现出来的。在Java的社区,你能看到更多的对模式、框架的讨论,而微软虽然自己做的东西很讲究模式和框架,但似乎更喜欢做好一堆全家桶给你,让你去做快速开发。

第三,对各种语言的感受,写起来最爽最有成就感的当然是C,那种一切尽在掌握的感觉是很奇妙的。不过我现在公司没有C/C++程序员了,因为公司不做游戏了,我也有起码5年没碰C了。我最喜欢的还是C#,我很崇拜安德鲁,C#的语法和机制真的设计的很精妙:泛型、delegate/event、Attribute、Lamda表达式、函数式编程,总觉得这个语言的设计给人一种特别的精致美感,能满足我对一门好的语言的所有的想象。自从.Net Core以后,跨平台也不是问题了。相对Java来说,我更喜欢C#。当然,我是不会排斥Java的,只要做Java能赚钱。

第四,我觉得数据结构真的非常重要,如果你想成为高手的话。在学校里面,一定要把这门课反反复复的学习。当然,如果你只想做做Web开发,写写网页的话,当我没说。

最后,对计算机专业的学生来说,我认为,在大学就是要打好基础。语言的东西真的不难,所有语言的编程思想都是想通的,语法其实也都大同小异,无外乎顺序结构、循环结构、分支结构。不用太焦虑应用型的开发,这些东西其实学起来是很快的。重要的是基础。C语言是必学的,学好C,让你对计算机的原理(数据结构、寄存器、内存、硬盘读写等等)有更深刻的认识。然后,为了工作,学学Java,学学C#。数据结构、编译原理这样的课程,当你工作年限变长,开始写架构、开始做性能优化的时候,你会觉得特别有用。当然,最开始的简单开发任务基本上用不着。不过,不想做高手的程序员,当然不是好程序员,是吧?

还有,其实我是非常建议,作为程序员,C#是必学的,不是因为我个人喜欢C#,是因为,实际上,按照我的习惯,在做项目的过程中,我经常会写一些小工具,而这些小工具,很多时候当然都是写成exe啦,所以,一般我都会选择用C#来写。

补充一点,我认为好的程序员不能把自己绑定在一种语言上,不能把自己就定义为JAVA程序员,C#程序员,等等。还是那句话,语言没有高下之分,只有适用的场景。好的程序员,应该有很快学会一种新的语言,并解决实际问题的能力。在我二十年的程序生涯中,有过不止一次,因为项目,一两天学一种语言的基本语法,然后边Google函数和库用法,边完成项目,然后项目完成后就扔一边的经历。
写程序,关键的是解决问题的思路,而不是语言本身。对语言来说,无外乎语法,函数,类库,现成的框架这些东西,这些都是“术”,而你对数据结构,设计模式,系统架构,计算机原理这些东西的理解,才是“道”。补充一点,对SSH这种现成框架的使用,并不能称为架构设计。

再举个例子,比如你要做网络编程,那么你对TCP/IP的理解,socket是怎么回事,怎么握手,怎么发送数据之类的理解是最基础的,是所有语言都通用的,至于最后你用JAVA来写,还是用C#来写,有多大区别?其实都是大同小异。
最后,要成为高手,学好英语,学会翻墙,一定要用Google。记住一点,凡是能百度到中文资料的内容,都已经不是“高级”的内容了。