一名优秀的工程师应该学会在工作中提升自己
引言
古人云:“活到老,学到老。”互联网算是最辛苦的行业之一,高额薪资意味着“加班”对工程师来说已是“家常便饭”,同时互联网技术又日新月异,很多工程师都疲于应付,叫苦不堪。以至于长期以来流传一个甚广的误解:35岁是程序员生涯的终点。
如何在繁忙的工作中做好技术积累,构建个人核心竞争力,相信是很多工程师同行都在思考的问题。本文是我自己的一些总结,试图从三个方面来解答:
-
一、学习的原则
-
二、成长难免伴随困惑
-
三、成为优秀的架构师是大部分初中级工程师的阶段性目标。
注:原文来自美团技术团队《工程师如何在工作中提升自己?》现结合自己8年的Android开发经验重构此文。希望可以给大家提供参考和借鉴。
一、如何学习
在繁忙的工作中,持之以恒、不断学习和进步是一件艰难的事情,需要强大的毅力和坚定的决心。如果方法不得当,更是事倍功半。幸好我们的古人和现在哲人已经总结了很多优秀的学习方法论,这里汇总了一些重要原则。遵循这些方法必会对大家的工作学习大有裨益。
1、贵在坚持
有报道指出,过去几十年的知识量超过之前人类几千年的知识量总和。而计算机领域绝对是当代知识更新最快的领域之一,因此,工程师必须要接受这样一个现实,现在所掌握的深厚知识体系很快就会被淘汰。要想在计算机领域持续做优秀架构师,就必须不停的学习,掌握最新技术。总之,学不可以已。
所谓“冰冻三尺,非一日之寒,水滴石穿,非一日之功”,通往架构师的道路漫长而又艰巨,轻易放弃,则所有付出瞬间付之东流。要想成为优秀的架构师,贵在坚持!
虽然知识更新很快,但是基础理论的变化却非常缓慢。这就是“道”和“象”关系,纵是世间万象,道却万变不离其宗。对于那些非常基础的理论知识,我们需要经常复习,也就是“学而时习之”。
2、重视实践
古人云:“纸上得来终觉浅,绝知此事要躬行。” 学习领域有所谓721模型:个人的成长70%来自于岗位实践,20%来自向他人学习,10%来自于培训。虽然这种理论存在争议,但对于工程师们来说,按照实践、学习和培训的方式进行重要性排序,大致是不错的。所以重视实践,在实践中成长是最重要的学习原则。
以学开汽车做例子,很难想象什么人能够仅仅通过书本知识或者看教学视频就能学会开汽车。
重视实践,充分运用感性认知潜能,在项目中磨炼自己,才是正确的学习之道。在实践中,在某些关键动作上刻意练习,也会取得事半功倍的效果。
3、重视交流
牛顿说:“如果说我看得比别人远一些,那是因为我站在巨人的肩膀上。”我们需要从别人身上学习。从老师、领导、同事、下属甚至对手身上学习,是快速成长的重要手段。
向老师和领导学习已经是人们生活习惯的一部分了。但是从同事甚至对手那里学习也很重要,因为这些人和我们自身更相似。所以要多多观察,取其所长,弃其所短。对于团队的小兄弟和下属,也要“不耻下问”。
4、总结和输出
工程师在实践中会掌握大量细节,但是,即使掌握了所有细节,却没有深刻的总结和思考,也会陷入到“学而不思则罔”的境地。成长的“量变”来自于对细节的逐渐深入地把控,而真正的“质变”来自于对“道”的更深层次的理解。
将经验输出,接受别人的检验是高层次的总结。这种输出不仅帮助了别人,对自身更是大有裨益。总结的方式有很多,包括组织分享,撰写技术文章等等。当然“日三省吾身”也是不错的总结方式。总之,多多总结,多多分享,善莫大焉!
解答别人的问题也是个人成长的重要手段。有时候,某个问题自己本来不太懂,但是在给别人讲解的时候却豁然开朗。所以,“诲人不倦”利人惠己。
二、成长难免的困惑
人生是一场马拉松,在漫长的征途中,难免有很多困惑。困惑就像枷锁,使我们步履蹒跚,困惑就像死锁,让我们停滞不前。
接下来我将总结自己在工作中碰到和看到的一些典型困惑。这些困惑或者长期困扰作者本人,或者困扰我身边的同事和朋友。当这些困惑被释然之后,大家都感觉如重获释,为下一阶段的征程提供满满的正能量。
人生就像一场旅途,不必在乎目的地,在乎的,应该是沿途的风景,以及看风景的心情。良好的心态是技术之旅最好的伴侣。期望通过这个解惑之旅,让大家拥有一个愉快的心情去感受漫长的学习旅途。
1、学无止境吗?
必须要承认一个残酷的现实:人的生命是有限的,知识却是无限的。用有限的生命去学习无限的知识是不可能完成的任务。一想到此,有些工程师不免产生一些悲观情绪。如果方法得当并且足够勤奋,悲伤大可不必。
虽然,人类的整体知识体系一直在扩张。但是就很多重要的工程细分领域,基础理论并不高深。计算机的很多重要领域,工程师有能力在有限时间内抓住核心要害。
技术学习是一场对抗赛,虽然学无止境,超越大部分对手就是一种胜利。所以,以正确的学习方式,长时间投入就会形成核心竞争力。
2、没有绝对高明的技术,只有真正的高手
致力于在技术上有所成就的工程师,都梦想有朝一日成为技术高手。但技术高手的标准却存在很大的争议。这是一个有着悠久历史的误解:以某种技术的掌握作为技术高手的评判标准。我经常碰到这样一些情景:因为掌握了某些技术,比如有一定的性能调优水平、比如对第三方库掌握的比较多等,一些工程师就自封为高手。
这种误解的产生有几个原因:
首先,技多不压身,技术自然是掌握的越多越好,掌握很多技术的人自然不是菜鸟。但也不一定是高手。
其次,在互联网时代来临之前,信息获取是非常昂贵的事情。这就导致一项技能的掌握可以给个人甚至整个公司带来优势地位。互联网时代,各种框架的出现以及开源的普及快速淘汰或者降低了很多技能的价值,同时降低了很多技术的学习门槛。所以,在当前,掌握某项技能知识只能是一个短期目标。怀揣某些技能就沾沾自喜的人需要记住:骄傲使人退步。
3、不做项目就无法成长吗?
在项目中学习是最快的成长方式之一,很多工程师非常享受这个过程。但是一年到头都做项目,你可能是在一家外包公司。对于一个做产品的公司,如果年头到年尾都在做项目,要不然就是在初步创业阶段,要不然就是做了大量失败的项目,总之不算是特别理想的状态。正常情况,在项目之间都会有一些非项目时间。在这段时间,有些同学会产生迷茫,成长很慢。
项目真的是越多越好吗?答案显然是否定的。重复的项目不会给工程师们带来新的成长。不停的做项目,从而缺乏学习新知识的时间,会导致“做而不学则殆”。真正让工程师出类拔萃的是项目的深度,而不是不停地做项目。所以,在项目之间的空档期,工程师们应该珍惜难得的喘息之机,深入思考,把项目做深,做精。
如何提高项目的深度呢?一般而言,任何项目都有一个目标,当项目完成后,目标就算基本达成了。但是,客户真的满意了吗?系统的可用性、可靠性、可扩展性、可维护性已经做到极致了吗?这几个问题的答案永远是否定的。所以,任何一个有价值的项目,都可以一直深挖。深挖项目,深度思考还可以锻炼工程师的创造力。期望不停地做项目的人,就像一个致力于训练更多千里马的人是发明不出汽车的。锻炼创造力也不是一蹴而就的事情,需要长时间地思考。总之,工程师们应该总是觉得时间不够用,毕竟时间是最宝贵的资源。
4、职责真的很小吗?
很多时候,一个工程师所负责系统的数量和团队规模与其“江湖地位”正相关。但是,江湖地位与技术成长没有必然关联。提升技术能力的关键是项目深度以及客户的挑剔程度。项目越多,在单个项目中投入的时间就越少,容易陷入肤浅。特别需要避免的是“ 在其位不谋其政”的情况。团队越大,在管理方面需要投入的精力就越多。在管理技巧不成熟,技术眼界不够高的前提强行负责大团队,可能会导致个人疲于应付,团队毫无建树。最终“ 一将无能,累死三军”,效果可能适得其反。
从技术发展的角度来说,技术管理者应该关注自己所能把控的活跃项目的数量,并致力于提高活跃项目的影响力和技术深度。团队人数要与个人管理能力、规划能力和需求把控能力相适应。一份工作让多个人来干,每个人的成长都受限。每个人都做简单重复的工作,对技术成长没有任何好处。团队管理和项目管理需要循序渐进,忌“拔苗助长”。
5、工程师天生不善沟通吗?
实际工作中,沟通所导致的问题层出不穷。工程师有不少是比较内向的,总是被贴上“不善沟通”的标签。实际上,沟通能力是工程师最重要的能力之一,良好的沟通是高效工作学习的基础,也是通过学习可以掌握的。
- 学会正确的提问
在平时的开发工作或者学习中遇见问题是很正常的事情,但是遇见问题的时,不要随便或者立即问其他人,要学会独立解决问题。先利用搜索引擎搜索一下,大部分的问题其实都能在搜索引擎上搜到,以免浪费大家的时间,另外,问题代表着突破自我的一个机会,给自己一定时间努力的去解决它,每一次畏惧就是一次退步,每一次突破就是一次积累。在尽力解决但无果的情况下,再考虑寻求他人的帮助,但提问的方式是有一定讲究的,因为不正确的提问浪费的是你和帮助者的时间,无法高效率的解决现有问题。常常在社区或者技术群里能看到一些这样提问:
你(有人)用过 xxx 吗?
xxxx 操作抛出问题,该怎么解决?
xxx 进行 xxx 操作,为什么不行?有人知道吗?
此时,[黑人脸+问好号.jpg]。
这里大家可以阅读下《提问的艺术》这本书,这是一本教你如何通过富有技巧性的提问来提高沟通效率并提升自身影响力的书。
Github 上一些开源项目会有 Issue Template,最主要的目的也是让提问者更仔细的去描述遇见的问题,让维护者更容易明白以及给出帮助。
6、效率重要吗?
经常看到有些同学给自己的绩效评分是100分——满分,原因是在过去一段时间太辛苦了,但最终的绩效却一般般。天道酬勤不错,但是天道更酬巧。工程师们都学过数据结构,不同算法的时间复杂度的差距,仅仅通过更长的工作时间是难以弥补的。为了提升工作学习效率,我们需要注意以下几点:
-
主要关注效率提升。很多时候,与效率提升所带来的收益相比,延长时间所带来的成果往往不值得一提。
-
要有清晰的结果导向思维。功劳和苦劳不是一回事。
-
做正确的事情,而不仅仅正确地做事情。这是一个被不断提起的话题,但是错误每天都上演。为了在规定的时间内完成一个大项目,总是要有所取舍。如果没有重点,均匀发力,容易事倍功半。如果“南辕北辙”,更是可悲可叹。
三、架构师能力模型
前面我们已经讲完了原则和一些困惑,那么工程师到底应该怎么提升自己呢?
成为优秀的架构师是大部分初中级工程师的阶段性目标。优秀的架构师往往具备五种核心能力:编程能力、性能优化能力、架构能力、项目管理能力和规划能力。
这几种能力之间的关系大概如下图。编程能力属于最基础的能力。连业务编程能力都无法掌握精通,很难在性能优化能力和业务架构能力方面有所成就。具备了一定的性能优化能力和业务架构能力之后,才能项目管理能力方面表现优越。团队管理能力是最高能力,它对项目管理能力的依赖度更大。
总结
架构师是程序员的终极梦想,为什么很多程序员做不了架构师呢?
1、良好健康的职业规划很重要,但大多数人都忽略了
2、学习的习惯很重要,持之以恒才是正解。
3、编程思维没能提升一个台阶,局限在了编码,业务,没考虑过选型、扩展
4、身边没有好的架构师引导、培养。所处的圈子对程序员的成长影响巨大。
文章到此就结束了,期望对工程师们的工作学习有所帮助。需要申明的是,文章内容挂一漏万,所谓的架构师能力模型也是作者的个人观点。欢迎大家在评论中分享自己在学习成长方面的心得。如果觉得有那么一点收获的话,希望可以得到您的关注、点赞和收藏。
最后是我整理的一份Android架构师技能树,有点长,有需要的朋友可以收藏起来,没兴趣可不看。
以下技术知识点系统的图文。视频学习资源在我的GitHub都有详细的讲解。
必备Java基础
泛型
- 作用于定义
- 通配符于嵌套
- Rxjava中的泛型
注解
- 自定义注解与元注解
- APT,编译时注解处理器
- 插桩
- 反射,运行时动态获取注解信息
- Retrofit
并发线程
- 线程共享与实现实现
- CAS原理
- Android AsyncTask原理
Java虚拟机
- Dalvik虚拟机
- CG算法、机制
- 内存分配策略
Hook技术动态编程
动态代理模式
双亲委托机制
JavaIO体系
IO操作Dex加密
数据结构及算法
数据结构
- 栈和队列
- 数组和链表,自定义一个动态数组
- Hash表,及Hash冲突的解决
- 二叉树
- B+ B-树
- 基础排序算法:重点 快排、归并排序、堆排序(大根堆、小根堆)
- 快排的优化
- 二分查找与变种二分查找
- 哈夫曼树、红黑树
- 字符串操作,字符串查找,KMP算法
- 图的BFS、DFS、prim、Dijkstra算法(高阶技能)
- 经典问题:海量数据的处理 (10亿个数中找出最大的10000个数 TOP K问题)
算法
- 分治算法
- 动态规划
- 贪心算法
- 分支限界法
Android基础
- Android Activity生命周期
- Application生命周期
- Android Service、IntentService,Service和组件间通信
- Activity的onNewIntent
- Fragment的懒加载实现,参数传递与保存
- ContentProvider实例详解
- BroadcastReceiver使用总结
- Android消息机制
- Binder机制,共享内存实现原理
- Android 事件分发机制
- Android 多线程的实现:Thread、HandlerThread、AsyncTask、IntentService、RxJava
- ActivityThread工作原理
- 嵌套滑动实现原理
- RecyclerView与ListView(缓存原理,区别联系,优缺点)
- View的绘制原理,自定义View,自定义ViewGroup
- View、SurfaceView 与 TextureView
- 主线程Looper.loop为什么不会造成死循环
- ViewPager的缓存实现
- requestLayout,invalidate,postInvalidate区别与联系
- AndroidP新特性
- Android两种虚拟机
- ADB常用命令
- Asset目录与res目录的区别
- Android SQLite的使用入门
Android开发高级
Android技术难点
AIDL、Binder、多进程、View的绘制流程、事件分发、消息队列等。
这类知识对于定位自己为高级Android工程师的人来说是必须掌握的,同时他也是能鉴别高级和初中级工程师的一块试金石,其中binder是Android系统进程间通信最重要的手段之一,现阶段app的发展离不开多进程的运用,经常会启动例如定位、推送等需要在后台开启动的进程来来保证主进程的内存运行;所以合理的使用多进程也是十分必要的;view的绘制是我们自定义控件的理论基础,只有掌握了view是如何绘制的才能个性化的自定义控件;事件分发一直是Android开发的难点之一,也是必须掌握的;关于handler机制也是android的一块难点,因为包括Asynctask、系统启动、Intentservice等底层都是通过handler来实现的,所以掌握后handler机制不仅能提高你的实战开发能力,更能让你系统的了解整个android系统运作的情况。
Android框架层源码掌握
- Android包管理机制,核心PackageManagerService
- Window管理,核心WindowManagerService
- Android Activity启动和管理,核心ActivityManagerService
- 根Activity工作流程
- Context关联类
- 各种原理,经典第三方库源码系列
- 自定义LayoutManager,RecyclerView中如何自定义LayoutManager
- VLayout实现原理,即如何自定义LayoutManager
- Glide加载原理,缓存方案,LRU算法
- Retrofit的实现与原理
- OKHttp3的使用,网络请求中的Intercept
- EventBus实现原理
- ButterKnife实现原理
- RxJava实现原理
- Dagger依赖注入
- 热修复实现原理,解决方案
- 组件化原理和解决方案
Android进程通信以及多进程开发
Android 多进程和Application关系
经典解决方案:多进程通信解决方案:Andromeda
- Android动画机制
- Android绘图原理
- Android页面恢复
Android的页面恢复采用以下两个方法:
- onSaveInstanceState(Bundle outState)
- onRestoreInstanceState(Bundle savedInstanceState)
onSaveInstanceState :当Activity容易被系统销毁时,会触发该方法。具体的说:
- 用户点击Home键
- 用户点击Home键,切换到其他应用程序
- 有电话来了等附加操作
混合开发及Android WebView应用
混合开发涉及到的知识点主要包括:
- APP调用WebView加载url
- 掌握WebView的封装,了解所有的WebSettings配置,掌握WebViewClient、* WebChromeClient
- 掌握WebView和Native双向通信机制,会自己封装双向通信中间件
- 对WebView的封装可参考:GitHub: AgentWeb
- 对通信中间件原理理解:GitHub:webprogress
Gradle,自动化构建,持续集成相关
Android系统
Android Studio编译过程
其中使用到的编译工具:
aapt、aidl、Java Compiler、dex、 zipalign
主要步骤描述:
- 通过aapt打包res资源文件,生成R.java、resources.arsc和res文件(二进制 & 非二进制如res/raw和pic保持原样)
- 处理.aidl文件,生成对应的Java接口文件
- 通过Java Compiler编译R.java、Java接口文件、Java源文件,生成.class文件
- 通过dex命令,将.class文件和第三方库中的.class文件处理生成classes.dex
- 通过apkbuilder工具,将aapt生成的resources.arsc和res文件、assets文件和classes.dex一起打包生成apk
- 通过Jarsigner工具,对上面的apk进行debug或release签名
- 通过zipalign工具,将签名后的apk进行对齐处理。
App启动加载过程
Android虚拟机 Android App运行的沙箱原则
Android架构
在Android源码中最重要的三个类:ActivityManagerService/PackageManagerService/View,推荐大家周末的时候可以去阅读下这部分的源码,阅读源码能提高我们今后设计架构自己代码的能力,同时也能从底层了解整个android系统的运行原理,其他一些比如主线程的消息循环、主线程如何和AMS如何跨进程交互、SystemServer进程中的各种Service的工作方式、AsyncTask的工作原理等。这些知识也是作为一个Android高级开发工程师必须掌握的,不能整天沉溺于ui和四大组件的交互,要站在更高的角度去考虑Android的有些问题。
- MVC模式
- MVP模式
- MVVM模式
- CLEAN模式
- 组件化开发
- 跨平台开发:Flutter、ReactNative(RN未来要黄,了解一下就好)
移动开发外围
服务器开发相关
- SpringBoot技术
- Restful API开发
- 网络协议理解:TCP/IP、HTTP/HTTPS、OSI七层协议
- 授权认证协议: OAuth2.0 等
- 基本的数据库技术
- 数据缓存技术v:Memcached、Redis,Web缓存原理
- 消息队列技术
- 监控、日志分析技术
前端开发相关
前端开发知识很多,框架层出不穷,本质的东西却只有以下这些。
- 核心必备:HTML、CSS、JavaScript
- 入门提高:浏览器兼容性、自定义UI和动效
- 中级技能:框架层出不穷,当前以vue.js、react.js 为核心
- 协作开发技能:包管理、模块化,工具采用 npm、webpack等
- 高级技能:框架原理源码研究
开发调试各种工具
- 性能分析工具:Memory Monitor
- 性能追踪及方法执行分析: TraceView
- 视图分析:Hierarchy Viewer
- ApkTool- 用于反向工程Android Apk文件的工具
- Lint- Android lint工具是一个静态代码分析工具
- Dex2Jar- 使用android .dex和java .class文件的工具