百万年薪程序员的7点能力

 

作者介绍

findyi,腾讯、360码农,前哒哒少儿英语技术VP,现任土豆教育CTO。

几周前,微盟爆了个大雷,数据库让内部员工删库跑路。写了篇文章,做了一些我的判断:从微盟36小时故障,谈谈数据安全这点事。

很明显,微盟的技术体系是有严重问题的,主要体现在:运维权限管理、数据库备份、上云而不上云方案,这三点。看起来有点耸人听闻,其实你永远不知道一个人或者一家公司的技术会低到什么程度,不少人可能从来都没用过GitHub和GitLab。

程序员这个行业,是一个区隔度特别高的行业。不少人短短几年就可以成长为高级工程师、资深架构师、首席架构师,而另外一部分人很可能工作10年还是初中级工程师。

程序员行业还有一个特点,优秀程序员的产出是普通程序员的好多倍,甚至是10倍!这是因为编程不是一门「线性科学」,而是一门「非线性科学」。

「线性科学」,比如跑步的速度就是,世界冠军的速度也不可能是普通人的10倍。「非线性科学」是指很多种因素交汇在一起,极大增加了系统的复杂度。

程序设计和实现不是一种线性能力,像经验、编码能力、工程能力、知识、学习新知识的能力、对无用部分的识别等这些就不仅仅是线性优势,汇聚到一起会对编程产生倍增级效应。

优秀的程序员能达到百万年薪,而入门级或者初中级程序员可能只能拿10万年薪。输出的10倍差距带来的是收入上的10倍差距!

很多时候,遇见复杂系统问题,派多少个初中级工程师都于事无补,而一个资深架构师就可以轻松搞定。

过去11年的职场生涯,我带过过百名程序员,见过非常优秀的也见过平庸的。以下是我认为程序员和普通程序员拉开巨大差距的7个关键点:


 1 

裸编程能力

裸编程能力:处理程序实际实现部分的子任务,实现函数或者算法之类的能力。听起来很简单对吧?实际上很多程序员缺失这样的能力。

不知道大家有没有见过「复制粘贴工程师」,review他们的代码甚至会发现一些网上的注释,又或者其他人的编写错误。

并不是所有程序员都具备利用必备的基本编程结构有效的实现某个产品或者某个模块。

不少工作多年的程序员甚至连一个简单算法排序都没有考虑,当然这并不影响普通工作的输出,但在面临调优或者攻坚,这类型的程序员的表现甚至比刚毕业的优秀程序员还要糟糕。

在工作中遇到过一次将代码时间复杂度降低几个数量级的情况,在压测模拟过万人同时使用的情况下,没优化前服务端程序直接卡死,优化后能流畅的运行。

在这个复盘过程中,我发现实现这个功能的程序员缺乏基础的算法基础。for循环的嵌套,简直是触目惊心。

BAT大厂招聘高级工程师,为什么总是要求手写各种算法,恐怕也是基于考察裸编程能力。


 2 

调试能力

调试能力某种程度上比编码能力更重要。查找和解决BUG会占用程序员大量的时间。查找BUG产生的根源不是一件简单的事情,需要整体的分析和经验的沉淀,同时还需要对各种调试工具熟练应用。

不少程序员,解决完一个BUG却导致了更多的隐患,没有真正把BUG产生的原因找到,只治标不治本。

对于程序员来说,掌握在合理的步骤内修复BUG,以极简的方式编写较少BUG的代码的能力,就能显著提升效率。

另外在团队中担任骨干的往往都是调试能力极强的程序员,在其他成员遇到困境之时,快速定位解决问题。

能否运用调试技能快速解决问题,是衡量一个程序员水平高低的重要标准。


 3 

追求简约

代码的注释是否恰到好处、函数模块和类的结构是否能让其他人直接秒懂、架构的设计是否足够清晰等等,都属于程序员追求简约的范畴。

有一种炫技程序员或者架构师,喜欢简单事情往复杂了做。明明几个类能搞定的,弄出很多中间类,明明三层架构就解决的问题,生生弄出五层。

简约是成败之间最为明显的分界点,事实上能做到简约的人,恰恰是深度理解了系统的复杂性。就好比微信是一个极度简约的产品,能做到这么简约恰恰是因为张小龙深度理解了通信和社交产品的复杂度。

一个产品功能,有人用了500行实现,你写了几千行。多出来的代码有价值吗?不仅没有价值,还会对未来接手代码的人有很大的困扰。less is more,简单就是美,这话说的真没错。

看看Google、Facebook等公司的源码,找不到太多多余的代码和结构。无论是代码层面、类层面还是架构层面,都做到了恰如其分、恰到好处。

不要多写一行无用的代码!


 4 

准确预测技术工期

老板想了个idea授意产品经理估工期。产品经理原型都没画出来,只有个大概想法,就找技术排工期。

这个时候,技术的内心大概多了几道菜式:清蒸产品经理、红烧产品总监、油炸CTO。

其实准确预测技术工期是程序员一项非常重要的能力。为什么这么说?只有具备这项能力,才能让开发工作游刃有余、可进可退。

事实上锻炼这种能力也并不困难,拿移动端开发来说,一个idea大概对应多少个页面多少个逻辑类,是能够估算出来的,以此为基础完全可以估出大概时间。更不用说产品文档出来之后的预测,会更为精准。

那么预测技术工期的意义在哪呢?

首先在没有出文档之前的估计,可以作为给老板的重要判断武器。做任何功能一定会投入研发力量,而往往研发力量是最宝贵的,如果在idea出来之后就能大概知道工期,对于做什么不做什么的判断,意义重大。

产品文档出来之后的精确工期呢?对控制风险和进度把控非常有帮助,这个时候的精确排期其实对风险点的估计、资源协调的能力都有很高要求。准确预测的过程其实就是风险预判的过程。


 5 

理解底层系统原理

处理复杂任务或解决复杂BUG时,具备深厚的底层系统知识非常重要。比如数据结构、网络协议、操作系统相关知识,等等。程序的很多问题都是源于对计算机工作原理的误解,即使是使用高级语言开发的程序也一样。另外,一些更偏应用层的架构或框架,基础一定是更底层的系统。

了解了底层原理,我们才能看穿眼花缭乱的技术背后的东西,不被层出不穷的新技术所累。

比如Docker技术兴起,改变了CI/CD的方式,推动了云原生技术的发展。那么Docker到底是什么东西呢,其底层无外乎:CGroups进行资源限制、Namespace对进程视图修改、rootfs为容器进程提供隔离后执行环境的文件系统。

了解了Docker的底层原理,才能在实际工作中更好的驾驭Docker。

再举个应用场景的例子:一提到分布式锁问题,大多数同学想到的方案是基于Redis的Master-Slave模式来实现。这个实现方案行不行?分布式锁本质是一个CP需求,基于Redis的实现是一个AP需求,乍一看基于Redis的实现是无法满足的。

脱离业务场景来谈架构都是耍流氓。从技术战略的需求层面来看,如果分布式锁在极端情况下获取锁的不一致,社交业务场景能够接受,那么基于Redis的实现是完全可行的。

如果业务是交易场景,分布式锁在极端情况下获取锁的不一致性无法接受,那么基于Redis的实现方案是不可行的。在锁强一致性的场景下,需要采取基于CP模型的etcd等方案来实现。

做出以上判断,需要深度理解底层系统原理。缺乏了这种理解,无法做出正确的架构抉择,也自然会对工作造成不利影响。


 6 

严格把控关键设计

无论是大的系统还是小的模块,一定都有最关键的功能。要在最关键功能上投入大量设计时间,才能规避开发过程中的各种坑。

程序员非常不情愿看到的一种情况是,需要在一些无关紧要的功能上浪费大量的时间,但你又不得不去将这个无关紧要的功能实现,因为它牵扯着这个项目的主要功能。

这种时候,就需要反思,在顶层设计的时候是否考虑周全。详细而缜密的顶层设计能够减少上述情况的发生,降低模块间的耦合性。

必须意识到每一个细小的模块都有可能成为项目的瓶颈。对于项目而言,最终的目标是合理的时间做最大的产出,实施重点就应该放在项目最主要的模块上。

拿设计IM功能来说,一个IM系统最重要的核心模块,一定是通信部分。将通信部分的各种设计搞定,其他锦上添花的方面都可以后续慢慢补充,例如客户端交互、好友关系等等。


 7 

拒绝完美主义

完美主义包含两种情况,一种是追求极致性能的工程师文化、还有一种是个人性格使然。无论哪一种,过分追求完美都会对业务交付产生影响。

完美主义会影响程序员的心态,过于担心外部评价或过于追求内心的安全,反而会导致设计上的过度和偏差。

程序员真正产生价值一定需要和业务结合,业务交付的及时性、健壮性、简洁性、可持续性一定是首先需要考量的事情。一定不能出现偏袒设计而牺牲生产力的情况。

不少创业公司上来就谈中台战略,并花大量研发力量去实践,最终中台没做好基础的业务保障也出问题了。在我看来,这也是追求完美主义的一种体现,诚然有一个类似阿里那样的能给各业务线赋能的中台是一个美好的愿望,但很多时候连业务方向都要多变,追求这种赋能无异于空中楼阁。

前几天我的读者群又有创业者在谈AI中台,我只想说既然是创业,咱能不能先MVP?等业务用户量更大了,再来追求更漂亮的实现?


最后的话

以上关于优秀程序员的7个能力,就说完了。其实还有一些通用的能力,比如高效学习能力、耐力、注意力等等,这些也是拉开程序员之间差距的重要因素。

今天还有个感悟:世界上的事情分两种,一种是有边界确定性强的事情:比如运动就会瘦、早起早睡会更健康、勤奋努力会具备架构思维。

另一种是无边界不确定的事情:比如练就6块腹肌、长寿100岁、成为首席架构师。如果我们连有边界确定性强的事情都搞不定还懊悔,那不要懊悔了,是因为我们压根没有真正渴望。

2020年,希望我身边的每个有足够渴望的程序员都能成为优秀的程序员。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310940.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《C++ Primer》13.1.1节练习

练习13.1: 如果构造函数的第一个参数是自身类类型的引用,且所有其他参数(如果有的话)都有默认值,则此构造函数是拷贝构造函数。拷贝构造函数在以下几种情况下会被使用: ●拷贝初始化(用定义变量&#xff09…

Java将五个整数存入整形数组_异常处理:从命令行输入5个整数,放入一整型数组,然后打印输出。。。...

从命令行输入5个整数,放入一整型数组,然后打印输出。要求:如果输入数据不为整数,要捕获输入不匹配异常,显示“请输入整数”;如果输入数据多余5个,捕获数组越界异常,显示“请输入5个整…

优秀的开发者从命名开始

有人说,命名能力也能体现一个程序员的基本编程素养。我很赞成这句话!作为开发人员逃不过起名字这一关的,大到项目名、模块名,小到类名、方法名、参数名、参数名、变量名。而命名又对代码的质量和可读性起到很关键的决定。如何码出高质量的代码…

【复杂系统迁移 .NET Core平台系列】之认证和授权

源宝导读:微软跨平台技术框架—.NET Core已经日趋成熟,已经具备了支撑大型系统稳定运行的条件。本文将介绍明源云ERP平台从.NET Framework向.NET Core迁移过程中的实践经验。一、背景随着ERP的产品线越来越多,业务关联也日益复杂,…

《C++ Primer》13.1.3节练习

练习13.9: 析构函数完成与构造函数相反的工作:释放对象使用的资源,销毁非静态数据成员。从语法上看,它是类的一个成员函数,名字是波浪号接类名,没有返回值,也不接受参数。 当一个类没有定义析构函数时&…

.NET Core开发实战(第30课:领域事件:提升业务内聚,实现模块解耦)--学习笔记...

30 | 领域事件:提升业务内聚,实现模块解耦我们在领域的抽象层定义了领域事件和领域事件处理的接口IDomainEventnamespace GeekTime.Domain {public interface IDomainEvent : INotification{} }这是一个空接口,它只是标记出来某一个对象是否是…

《C++ Primer》8.1.2节练习

练习8.1: #include <iostream> #include <stdexcept> using namespace std;istream &f(istream &in) {int v;while (in >> v, !in.eof()) {if (in.bad())throw runtime_error("IO流错误");if (in.fail()) {cerr << "数据错误&…

.NET 5 Preview 1的深度解读和跟进

这几天微软.NET 团队发布了.NET 5 Preview 1, 如约而至。很兴奋&#xff0c;因为.NET Core和.NET Framework终于实现了大一统&#xff0c;同时也很期待&#xff0c;期待.NET 5能给我们带来哪些好的新特性。让我们先把时间拨回到2019年...一、2019年.NET 5的提前剧透去年2019年 …

程序员羽化之路--假如需要一百万个对象

点击上方蓝字关注我们菜菜哥&#xff0c;救命呀又被产品经理砍了&#xff1f;这次搞不好真要被砍了&#xff0c;线上一个用户系统内存溢出了&#xff0c;占用内存太高了用户基数大&#xff0c;内存占用高正常高的不太正常了&#xff0c;我觉得可能和我的设计有关那说说你的用户…

WTM 3.5发布,VUE来了!

千呼万唤中&#xff0c;WTM的Vue前后端分离版本终于和大家见面了&#xff0c;我曾经跟群里1000多位用户保证过Vue版本会在春天到来&#xff0c;吹过的牛逼总算是圆上了。卧槽&#xff0c;NB啊!我等到花都谢了风太大&#xff0c;吹瞎了朕的双眼我是谁&#xff0c;我在哪儿&#…

java 第三方序列化,11.既然有第三方的序列化方式,说明java官方提供的序列化方式应该有一些很明显或者很致命的缺点……...

序列化是什么&#xff1a;把一个java对象转化为二进制对象&#xff0c;并保存到硬盘&#xff0c;或在网络上传输。反序列化就是把序列化的二进制对象读到内存中。 作用&#xff1a;1、减少内存占用或网络传输。比如web容器中的session&#xff0c;当session数量过大比如10W连接…

2020年,我来盘点下微服务架构技术栈

2020年了&#xff0c;很多小伙伴儿对微服务还比较陌生&#xff0c;说起来很多人可能不敢相信&#xff0c;其实微服务这个概念早在2012年就提出来了&#xff0c;经过了这些年的发展&#xff0c;现在已经成为企业非常主流的架构选项了。今天&#xff0c;我就来带大家一起探讨下微…

2.5w字长文爆肝 C++动态内存与智能指针一篇搞懂!太顶了!!!

动态内存与智能指针1.动态内存与智能指针2.shared_ptr类2.1.make_shared函数2.2.shared_ptr的拷贝和赋值2.3.shared_ptr自动销毁所管理的对象2.4. shared_ptr会自动释放相关联的内存2.5.使用了动态生存期的资源的类2.6.定义StrBlob类2.7. StrBlob构造函数2.8.元素访问成员函数2…

ASP.NET Core应用的7种依赖注入方式

ASP.NET Core框架中的很多核心对象都是通过依赖注入方式提供的&#xff0c;如用来对应用进行初始化的Startup对象、中间件对象&#xff0c;以及ASP.NET Core MVC应用中的Controller对象和View对象等&#xff0c;所以我们可以在定义它们的时候采用注入的形式来消费已经注册的服务…

ASP.NET Core 3.x - 为什么采用新的 Endpoint Routing 路由系统

Endpoint Routing 路由系统ASP.NET Core 3.x 使用了一套叫做 Endpoint Routing 的路由系统。这套路由系统在ASP.NET Core 2.2 的时候就开始露面了。这套Endpoint Routing路由系统提供了更强大的功能和灵活性&#xff0c;以便能更好的处理请求。早期ASP.NET Core的路由系统我们先…

《C++ Primer》10.1节练习

练习10.1: #include <iostream> #include <vector> #include <algorithm> using namespace std;int main() {vector<int>vi;int val;vi.push_back(45);vi.push_back(45);vi.push_back(45);vi.push_back(45);for (int i 1; i < 45; i) {vi.push_ba…

Asp.Net Core AuthorizeAttribute 和AuthorizeFilter 跟进及源码解读

一、前言IdentityServer4已经分享了一些应用实战的文章&#xff0c;从架构到授权中心的落地应用&#xff0c;也伴随着对IdentityServer4掌握了一些使用规则&#xff0c;但是很多原理性东西还是一知半解&#xff0c;故我这里持续性来带大家一起来解读它的相关源代码&#xff0c;…

1张手稿图讲明白 Kubernetes 是怎么运行的

注意&#xff1a;如果您已经知道Kubernetes的工作原理&#xff0c;那么您可能会对我之前的博文感兴趣&#xff0c;请停止使用具有管理员权限的kubeconfigKubernetes是最初由Google设计的开源工具&#xff0c;现在由 Cloud Native Computing Foundation&#xff08;CNCF&#xf…

就喜欢用vSphere部署K8s集群,不全是因为自动化!

通过努力&#xff0c;我们有了一个完整配置的工作负载域&#xff0c;其中包括一个NSX-T Edge部署。现在&#xff0c;我们准备继续使用Kubernetes 部署vSphere。通过VMware Cloud Foundation 4.0中的SDDC Manager&#xff0c;我们确保NSX-T Edge可用&#xff0c;并且还确保Workl…

同源策略_如何支持跨域

欢迎大家阅读《朝夕Net社区技术专刊》我们致力于.NetCore的推广和落地&#xff0c;为更好的帮助大家学习&#xff0c;方便分享干货&#xff0c;特创此刊&#xff01;很高兴你能成为忠实读者&#xff0c;文末福利不要错过哦&#xff01;01PARTCoreWebApi的调用1.在Core MVC下建立…