我在刚开始学编程的时候就经常来博客园,当时博客园基本是.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哪个好么?

虽然不抱希望但也愿.Net和Java之争暂得平息的更多相关文章

  1. memcached学习(3)memcached的删除机制和发展方向

    memcached是缓存,所以数据不会永久保存在服务器上,这是向系统中引入memcached的前提. 本次介绍memcached的数据删除机制,以及memcached的最新发展方向--二进制协议(Bi ...

  2. memcached全面剖析–3. memcached的删除机制和发展方向

    memcached在数据删除方面有效利用资源 数据不会真正从memcached中消失 上次介绍过, memcached不会释放已分配的内存.记录超时后,客户端就无法再看见该记录(invisible,透 ...

  3. memcached全面剖析--3

    memcached的删除机制和发展方向 下面是<memcached全面剖析>的第三部分. 发表日:2008/7/16 作者:前坂徹(Toru Maesaka) 原文链接:http://gi ...

  4. .NET入行之工作前

    时间就像轻风一样,刻意感受的时候几乎把你吹倒,不留意的时候又从你身边轻轻飘走了:长此以后,我怕自己会变得麻木,忘记了原来的样子.所以还是决定给自己留点什么,万一哪天忘记了,还可以再翻起来. 工作两年的 ...

  5. memcached全面剖析--3.memcached的删除机制和发展方向

    下面是<memcached全面剖析>的第三部分. 发表日:2008/7/16 作者:前坂徹(Toru Maesaka) 原文链接:http://gihyo.jp/dev/feature/0 ...

  6. OSChina 清明节乱弹 ——准备好纸巾了看乱弹

    2019独角兽企业重金招聘Python工程师标准>>> Osc乱弹歌单(2017)请戳(这里) [今日歌曲] @亚麻仔 :分享 范忆堂 的歌曲<酡颜 (夏热版)> 同一个 ...

  7. 【已解决】Https请求——基础连接已经关闭 发送时发生错误

    本人在做商用项目的推送消息功能时,借助第三方推送服务.这里避免有打广告的嫌疑,就不报名字了.由于是通过调用API接口,所以Post方法是自己写的,但是在开发环境是可以正常推送的,但是一上线就出各种问题 ...

  8. EntityFramework 7 Join Count LongCount 奇怪问题

    先吐槽一下,EF7 目前来说,真对的起现在的版本命名:"EntityFramework": "7.0.0-beta1". 这篇博文纪录一下:当 Linq 查询中 ...

  9. HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法

    [问题] 用C#模拟网页登陆,其中去请求几个页面,会发起对应的http的请求request,其中keepAlive设置为true,提交请求后,然后会有对应的response: resp = (Http ...

随机推荐

  1. 痞子衡嵌入式:ARM Cortex-M文件那些事(2)- 链接文件(.icf)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是嵌入式开发里的linker文件. 在前一节课源文件(.c/.h/.s)里,痞子衡给大家系统地介绍了source文件,source文件是嵌入 ...

  2. Spring AOP中的JDK和CGLib动态代理哪个效率更高?

    一.背景 今天有小伙伴面试的时候被问到:Spring AOP中JDK 和 CGLib动态代理哪个效率更高? 二.基本概念 首先,我们知道Spring AOP的底层实现有两种方式:一种是JDK动态代理, ...

  3. Python并发编程之谈谈线程中的“锁机制”(三)

    大家好,并发编程 进入第三篇. 今天我们来讲讲,线程里的锁机制. 本文目录 何为Lock( 锁 )?如何使用Lock( 锁 )?为何要使用锁?可重入锁(RLock)防止死锁的加锁机制饱受争议的GIL( ...

  4. C#线程同步--线程通信

    问题抽象:当某个操作的执行必须依赖于另一个操作的完成时,需要有个机制来保证这种先后关系.线程通信方案:ManualResetEventSlim.ManualResetEvent.AutoResetEv ...

  5. _C#发送邮箱

    public ActionResult lead() { SendEmail("邮箱号", "吃饭么?", "你要吃什么啊"); retur ...

  6. [Go] golang的error接口

    error接口1.error就是一个接口interface2.属于errors包,该包有一个导出方法New,返回了errorString类型3.errorString类型实现了error接口4.之所以 ...

  7. Fundebug前端JavaScript插件更新至1.7.1,拆分录屏代码,还原部分Script error.

    摘要: BUG监控插件压缩至18K. 1.7.1拆分了录屏代码,BUG监控插件压缩至18K,另外我们还原了部分Script error,帮助用户更方便地Debug.请大家及时更新哈~ 拆分录屏代码 从 ...

  8. 纯css做幻灯片效果

    css3里面有一个@keyframes动画功能. w3c上面的例子: 可以使用它来做一个幻灯片效果. <!DOCTYPE html> <html lang="en" ...

  9. 驰骋工作流引擎JFlow与activiti的对比之2种结构化模式

    1. 任意循环(Arbitrary Cycles) ACTIVITI : 某一个或多个活动可以反复执行. 例子:用户买了瓶汽水,拿到汽水后,中了一瓶,又去兑换了一瓶汽水,如果又中了,再去兑换一瓶汽水- ...

  10. mysql 的链接字符

    mysql的链接字符: driver =com.mysql.cj.jdbc.Driverurl =jdbc:mysql://localhost:3306/oa?serverTimezone=Asia/ ...