前言
我相信每个工程师都曾怀揣一个成为技术大牛的梦想,可是真正走向技术大牛这条路的少之又少。工作中我们常常会发现,有些同学工作没几年但成长迅速;很快就能走向团队核心岗位,成为一名优秀的工程师;而有些同学工作几年后却在公司里默默无闻,能力和职位上都没有太大提升,得过且过最终沦为一名普普通通的码农。所以我常常会有感慨,太多人(包括我自己)真的只不过是用一两年的经验在职场上混了五年十年甚至更久。
那么普通工程师和优秀工程师到底差距在哪儿?那些优秀工程师是怎么一步一步成长起来了的呢?以下就我自己的观察和思考来谈一谈,看看能不能一探究竟,了解通向优秀工程师的法门;然后与大家共勉,一起朝着优秀工程师的方向去努力。
一、差距在哪儿?
我们拿吴军老师在得到专栏中讲解的一道 Google 面试题来展开聊一聊,看看面对同样的问题,普通工程师和优秀工程师是如何思考解决问题的。
问题如下:如何设计一个地图功能,找到离当前最近的加油站?
在最近公司的招聘面试过程中,我也拿类似的问题去问过部分候选人,大部分候选人都把问题想的太简单。通常普通工程师给出的解决方案是:根据经纬度算出所有加油站到当前位置的距离,然后对这些加油站按照距离的远近进行排序,选择距离最近的几个加油站。
可问题是,在路面上行驶,从 A 点通往 B 点,往往不是直线距离。因为无论是驾车还是步行,我们都不可能穿过建筑直达目的地,A 点到 B 点的距离是很多距离片段的组合,这可能会有上千种组合,那么如何从这上千种组合的路线中选择距离最近的一条路线呢?使用动态规划算法能够很好的解决这个问题,在上千种组合中只需几十个步骤就能计算出最短路线。这对部分工程师已经是个门槛了。
接下来就需要按照距离排序,找到最近的几个加油站。
绝大部分工程师面对这样的问题都会想到排序,排序当然能够解决问题,但并不是最优方案。就算使用效率最高的快速排序,也需要 N 乘 LogN 的计算量。假设城市里有 1000 个加油站,那么 LogN 约等于 10,也就是说计算的复杂度差不多是 1000,当然 1000 的计算量对于计算机算不上什么,但是考虑到一个城市的路面上可能有上百万辆行驶的汽车,这个计算量的消耗就很可观了。
假设我们只需要最近的 5 个加油站,如果对所有的加油站排序那显然做了很多无用功。数据结构中有一种叫二叉树的数据结构,在二叉树中有一种更细的分类:“堆”,通过堆排序我们可以只用排出前几名,而不用管后面的名次。通过堆排序排出第一名的时间复杂度是N,排出第二名、第三名、第四名、第五名的时间复杂度都 LogN,比对 1000 个加油站排序要快的多。对于我们的需求:选出最近的 5 个加油站,差不多只需要 1000 的计算量,比快速排序快了近 10 倍。
到这里你是不是觉得问题已经解决的很完美了?
我们在解决问题的时候不由自主的做了一个假设,就是整个算法的优化过程是围绕一个使用者的某一次使用来进行的。但是在现实生活中,一个城市里有很多人会同时在不同的地方寻找加油站。类似的,同一个人在不同的时间不同的地点开车时也需要寻找加油站。考虑到这个现实场景,时时刻刻都有很多人在不停的寻找附近的加油站,那么很多计算其实是可以预先算好的,等到提供服务的时候直接把结果调出来就好了,避免重复计算。
比如我们可以把上海市所有路口点到点的距离事先计算好,当一个人要找加油站的时候,距离的计算就不再需要实时地采用动态规划来计算了,只需要计算从当前位置出发到附近几个路口的距离,再计算下某个加油站到它所在地附近路口的距离,由于各个路口点到点的距离是事先计算好的,因此做几次简单的加法即可,这样计算距离的时间就能省几十倍。这就是对上面的问题进行了全局优化的好处。
其实面对这样的问题,优秀的工程师并不会遇到问题就直接着手去解决,而是会更全面的去考虑问题。比如会考虑到目前的行车方向,比如在解决问题中其实距离要求并不需要太精准,因为对于开车的人来说 2.5 公里和 2.3 公里其实并没有什么差别,再考虑到道路拥堵的情况,200 米的距离更加可以忽略不计了。但如果是行人要寻找附近的便利店,200 米的距离就不得不考虑了。
那么从上述这个问题的解决上我们能看出普通工程师和优秀工程师的差距在哪儿呢?
1. 优秀的工程师必然有着扎实的计算机基础知识,很好的掌握了如数据结构、算法这些工具,能够在工作中借助这些工具帮助自己解决问题;
2. 优秀的工程师会尽量避免做无用功
3. 优秀的工程师不会只满足于完成任务,他们会不断的去思考探索最佳的解决方案;
4. 优秀的工程师不会被思维所局限,考虑问题更加全面,懂得从全局角度优化解决方案。
从这个例子我们也能看出来,一个优秀工程师解决问题的性能可能是普通工程师的几百上千倍,一个优秀的解决方案甚至能帮助公司节省几百万的服务器费用。
因此,在软件工程领域一百个臭皮匠也顶不了一个诸葛亮!
二、做为普通工程师的我们如何提升自己?
学好数据结构、算法、操作系统原理、计算机体系结构等基本功,打好基础。
如果你是天才,面对像上面这样的问题,即使你没有学过计算机理论知识,即使你不知道动态规划、二叉树、堆排序,可能也能依靠智力上的优势解决。但遗憾的是绝大多数人都不是天才,因此在解决问题的时候就需要借助各种工具以便事半功倍。对于开发人员来说,数据结构、算法以及各种数学知识就是我们手上的工具。
要成为优秀的工程师需要我们静下来,沉下去,老老实实的吃透你所做的项目。做好简单的事,才有机会去做更有挑战的工作。
很多工程师会抱怨自己一直在做业务,没什么挑战,感觉不到成长。可事实真的是这样吗?往往我们的业务需求就像这道面试题,看似简单其实想要做好,背后需要下很大功夫。就算平时做的业务真的很简单,我们是不是还可以想想,我的代码实现是否有更好的方式?面对类似的业务我的效率是否可以提升?线上出 Bug 了是否可以采集到线上 Log 快速定位并解决问题?你对自己开发的项目中用到的各种框架是否真的理解其原理,是否真的去翻过代码学习过这些优秀框架的实现?就拿 Android 开发来说,各种开源框架如 RxJava、Retrofit、OKHttp、ORM框架、热修复框架、插件化框架等等,如果你真的去认真学习过一遍,我相信已经远超行业里 90% 的工程师了。
同时在工作中要有不怕吃亏的心态,主动去承担更多的职责;做的更多往往也意味着接受了更多的挑战,获得了更多的锻炼机会。
利用碎片时间系统化学习
很多人反对碎片化学习,但我并不完全认同这种看法。碎片化的时间既可以用来碎片化的学习,也可以用来做系统化的学习。很多人都指望能够有一天,有一大片的时间,好好的、系统化的把计算机知识恶补一遍。所以买了算法导论、深入理解计算机系统等等经典书籍放在家里,等着有一天能够有一大片时间,沐浴更衣、正襟危坐来好好学习。但是学了不久很快又被其它事打断了,结果下一次又重新再来。最后往往只是把一本书的前几十页反复看了好多遍,其实这种才是真正的碎片化学习。
而所谓的利用碎片化时间系统化的学习是指制定好完善的学习计划,利用好每一个碎片时间,比如上下班的路上、等公交的时间、坐地铁的时间、排队的时间,甚至是蹲马桶的时间来按计划的、体系化的学习提高。
持续学习,坚持阅读,保持输出
技术更新迭代太快,而计算机科学之复杂也远不是在学校的几年学习就能完全学透的,这就要求我们保持持续学习。但往往很多人走出校门后就再也没有正儿八经的学习过、冲过电,这也是为什么我们毕业后会被那些优秀的工程师越甩越远的原因。而我认为最好的持续学习的方式就是坚持阅读了。你们看!优秀的工程师就算是挂着盐水也要坚持阅读的!!!
另外学过的知识只有输出出来了,才是真正的学到肚子了。向别人讲述知识、写作等都是很好的知识输出方式。
锻炼自己的综合能力
要成为一名优秀的工程师,光有过硬的技术是不够的。出色的完成一项工作往往考研的是一个人的综合能力。良好的表达能力、出色的会议组织能力、事情的推动能力、个人的成熟度等等都是需要我们在工作中去刻意的培养和锻炼的。拿表达能力来说,如果觉得自己表达上有所欠缺,就可以通过写作、主动在团队内做技术分享等等方式来锻炼自己。有时候,不逼自己一把你都不知道自己到底有多棒!
三、系统高效科学的学习方法
清晰的学习路线+对应系统的学习笔记+系统学习视频
如学习NDK模块
-
学习路线
-
对应系统的学习笔记
-
学习书籍
-
学习视频
由于文章篇幅问题查看详细文章以及获取学习笔记可以在我的【Github】里可以查看
四、写在最后
作为一个技术上的菜鸟,写这样的文章实在是有点惭愧。且算是给自己定个基调,与大家共勉好了,这样也能督促自己不断进步。
哦,对了!还有一点!!!优秀的工程师是不会抱着手机抖音一刷一晚上的。
网友评论