我在刚开始学编程的时候就经常来博客园,当时博客园基本是.Net的天下,从那时开始.Net和Java哪个好就一直在打,这些年没怎么看博客园了,回来发现到了今天居然还在争论,让我不由得想来分析一下这个问题,这里只考虑技术层面,而不谈什么大道理。
第一是大家关心的整体薪资分布,作为工程师或高级工程师,决定薪资的因素很多时候不光决定于你的技术,也决定于公司规模和制度,比如996拿得相对多自然付出的也多,所以单纯看月薪统计数据恐怕意义不大,这通常取决于你的贡献,再者薪资冒尖的一部分人必定不只会一门技术。
第二点是薪资的增幅,以Java来说,作为一个学生会不会用SpringBoot体系或者说用得好不好可能是五千和一万的差别,但是如果你已经月薪两万开外了,再去学一个PHP或者django之类的框架对你的薪资增幅毫无疑义,且你会发现你学会这些东西需要投入的成本可能不到一周,但是你学第一门可能花了之少好几个月,也就是说在同一个开发范畴之内(比如Web开发)对具体语言或框架在战术层面的投入带来收益的增速是衰减的(二阶导数为负),最终会逼近一个天花板,你不得不另谋出路。
第三是职业分工,我不懂为什么很多程序员都喜欢标榜自己是“Java程序员、Node程序员、.Net程序员、python程序员“等等,你们都是”Backend Engineer“,五岳能不能并派啊?不会触类旁通的只能说是瘸腿工程师或者图样,我还真不信让一个只写过.Net的人在一周内用flask做个API他做不了,我也不信什么能搞EF的搞不了JPA,能自给写出一套Spring的人会怕.Net换Java么,撑死了抽一天看看动态代理而已。严重依照技术栈招聘的,我只能说要么技术部门现在缺这么个人,要么在某种程度上来说能反应公司整体的管理风格和业务特点,好比卖OA的一般Java或.Net系统比较成型了,而高吞吐量的公司可能要招Node、Golang之流,然而你能说这俩东西Java工程师稍微学一学搞不来么?
第四是一些通的东西,以B/C模式开发整个技术栈来说,前端/微信之类的平台、移动开发、服务端开发、大数据端开发/BI开发、DevOps、和可能涉及到的机器学习,每一个里面都是一大套体系,又不是一个语言一个框架的事,我不敢说这里面哪一样只懂个.Net或者Java就能搞定你的工作,虽然有些东西是通的,比如这些里面很多都要用Redis,那Java和.Net的SDK有什么本质区别么?
吐了一堆槽,想说的是很多时候你要面对的问题,并不是Java哪种new字符串的姿势更科学,你非纠结这个的话翻翻面试宝典抄一个行不行?也不是.Net和Java哪个快,你能以一己之力撬动整个公司的决策的话,想必你也不会纠结哪个语言好了。我已经染指过很多门主流语言了,诚实地说,你问我这些语言的for循环怎么写,我肯定告诉你“复制粘贴”。
学编程,我认为可以多思考这种东西,下面随想随写,单拿编程语言一个范畴举几个例子:
1.拿for循环来说,我想到for循环,就想到迭代器,拿到任何语言,我就会找类似于iteratable的接口,进而想到函数式的foreach匿名函数之流,会留意集合的不可变性和并发问题,哦,记得Flux里也对不可变有要求,等等,这些东西放到任何语言里皆准
2.现在重新看Java设计模式,我会想起Scala的单例对象、lazy关键字、iOS的delegate实现、C#的委托实现,不再会纠结各种什么工厂而是知道把new的逻辑单拿出来拾掇拾掇,自己写个什么IoC,写个什么连接池任务池,知道抽象能自聚合实现链式调用等等,放到任何语言里皆准
3.想异常处理,会考虑异常在架构上的边界和异常管理,Golang的强制返回err是不是比Java的try更安心,有什么能彼此借鉴的,想到监控日志报警一条龙
4.看到JS有事件队列,安卓和iOS有事件循环,就考虑接Web请求的程序是不是也能自给弄个守护线程之类的
5.看到JS的引用计数在前端造成内存泄漏,就思考iOS的自动释放池机制,就去对比JVM的GC,在Hadoop之类的场景为什么会GC时间过长等等,大数据框架为什么要选JVM语言?
6.这个语言的并发包有栅栏工具、换个语言也有,这个语言能把线程当对象管理,换个语言我能不能很好地监控线程,换了协程咋弄,换了bash咋办
7.bash既然那么恶心我能不能换python?这个项目的后端要搞大把JavaBean还要写一堆for处理数据我能不能换pandas?
8.C#的IL是把linq这种函数式用OO实现了一把,拿来对比JS的实现,再考虑python,再反观Java7,最后为何不投奔Scala?
9.要说真麻烦的,还真是各种语言的环境配置和依赖管理了,那就让他们HTTP通信,docker怎么样?能不能考虑JSON之外的通信协议?
现在在争.Net和Java的人,将来你面对的工作可能是这样的:这个项目的特性是什么,我们选什么语言、DB或组件、云服务组件,这个语言的什么框架好,要什么API、如何组织它们协作,如何结合team现状拆分人员,怎么管元数据、版本、异常监控、要不要强制TDD、是DDD还是从前打到后、怎么运维、负载如何、怎么应对将来变化、机器学习是自己训练还是拿人家的、这部分自己做还是外包、数据处理流程是什么、安全管理怎么做、持续集成用什么、如何控制成本、这些东西怎么复制到下个项目里...你写的每一行代码长得再丑,背后都是满心的纠结
回到上面说的几点问题
第一点,对于码农来说,薪资天花板不是语言带来的,而是你能解决问题的复杂度,.Net也好Java也罢,无非就是个工具,除此之外还有很多工具,能砍掉PM需求的脑子和嘴皮子也是个工具,不要把某一个工具看得过于当看的,鄙视链就是个闹剧噱头,居然会有人当真?
第二点,作为后端工程师为了推迟天花板的到来,应该带着现有的技术跳去其他技术领域,比如Java可以跳大数据会迫使你跟进Python或Scala,比如去做高负载高并发的内容可能迫使你学习Golang、微服务、乃至bash,再走向DevOps,而做大数据也需要Ops,而做前端的不妨从Nginx开始从网络领域渗透到后端,另外像爬虫和数据分析这种东西如果不求太精则是谁都能去玩的,但是这里不建议往移动开发这种相关性低的领域跳。当你在技术上的投入带来的技术成长逐步趋于平缓之后,由于之前的充分综合积累,自己能发挥的价值还是会不断增加的。
第三点,深度是建立在广度的基础上的,我认为码农在一年后,发展应该先有一定广度,在这个基础上找一个领域深挖,就好比从大学读到博士,专业面虽然逐渐缩小,但也是建立在广度之上的,没有相对全局的视野,战术上的勤奋偶尔也会让你一时走错路,何况你不知道各种聪明的码农在愁烦什么的话,也别谈管人了。相比对于广度的投入来说,对某一个具体框架源码的研究带来的整体收益可能很小,这种事情并不在98%的需求范围内,除非你投入开源,或者进了阿里这种要自己写架构的厂写架构。
第四点,说到分工范畴,虽然不要求跨领域面太广,而我不敢想象一个.Net的OA开发人员一辈子都搞这个学生都能玩的CRUD夕阳产业,除非他把自己禁锢在这个领域,而不把自己真正当作一个后端工程师来看。而不论转什么都有一些通识,比如模式DDD、TDD、ORM原理、多线程、FP、数据结构性能估算等等,加之DB优化、网络协议、分布式原理等非编程语言内容也是通的,而换一种语言无非换一层皮,廖雪峰的python教程能让你两天看懂,不就是因为你有通识么?一个自称前端工程师的人我也不相信他只会JS不会其他TS等,一个自称数据工程师的人也不至于彻底不沾染机器学习。
有时候需要站在一个34岁有幸没有被开除还混到开发部经理的人的角度反过来看程序员的技术成长,而不是站在现在的位置歪歪将来如何。
如果你能忍耐着看到这里,现在可以回答我.Net和Java哪个好么?