程序员的能力

become a better coder

Posted by 宸笙 on February 4, 2019

其实在之前就很想写一篇类似的blog,当从业几年后,随着自己遇到同行的人越多,自己会遇到一些高手,他们不仅出活快,在解决bug也有自己的一套方法论,快速找到问题所在,你会好奇怎样达到的;也会遇到相对反面的,好奇怎么会这样;其实只要是个主动反思的有心人,都会学习到和总结到一些这方面的经验,在Bmob时,因为创业公司人手有限,除了负责SDK的优化改造,也作为技术支持对接大量的用户(企业用户或个人用户),接触的既有深谙开发之道的经验资深的程序员也有一些在校生的准程序员,在和他们沟通对接的过程中总能发现一些规律或问题,在反思自家SDK的用户体验时也能看到一些作为程序员的思维惯性(其实很多时候专业程度虽代表对某一领域的熟悉程度但也是一种惯性定势),当看到一些现象也会和kun哥交流下,也会反思自己,怎样才能做到更可靠,写此文也是这个目的。

main

我的入行

高中信息技术课一次老师拿大学计算机网络组网期末试题讲解和编程相关发现很感兴趣,那时刚好Android手机和国内山寨平板雄起,高三紧张备考的时候还不忘把玩仅有的那台歌美平板,玩过刷机烧录固件升级,也写过简单的网页代码,从百度文库下的Android编程资料发现不太好读懂,不过也确定了要做手机软件;高考后如愿选择了计算机专业,在很多人迷茫的大一大二,体会到了编码成功运行的那种成就感,大一看过麦可网sunnymars的Android课程,后陆续看过高焕堂先生的进阶architect相关(可能一些Android老手就比较熟悉),大二(2013年底)进入实验室参与企业项目,大三下学期去了某互联网公司实习,大四后半段在某云服务公司从事SDK开发相关,也因为这个契机,接触了很多开发者,在帮他们解决问题和完善公司产品的同事也经常会反思作为程序员的交流效率和解决问题的能力。

那些开发者

在某云服务公司,除了负责SDK开发相关,也直接作为技术支持对接大量的开发者,他们基本属于下面的几大类别:

  1. 知名公司的程序员

    这种基本是沟通效率最高的,印象比较深刻的一个便是番茄TODO的作者,来自美团,在使用友商的服务后迁移到了这边,沟通到一个点赞的数据表设计,在SDK这边的角度和他说怎样建表(Bass产品的特点是客户端程序员也需要懂点后端的基础)后的结构写代码是比较省事的后他马上知道怎么做了,一点就通;还有在阿里的猫哥,用了自家的推送SDK并在慕课上开课讲大厂App项目架构,他也在云平台的API上自己封装了一层,一些资深的开发者确实用的很溜,在沟通的时候他也和我说到了在SDK上实现热修复,说到那边的阿里游戏热修复已经用在了很多业务线上;也有圈内知名的徐宜生,除了在慕课上讲解Bmob的使用,在他的书Android群英传也有涉及;有的也能给SDK的一些使用方式,API等提出困惑或者是建议,有少数还是不错可以考虑加到更新计划中的,当然这部分的开发者比较少,也基本是个人应用。

  2. 中小公司的程序员

    这部分应该是最多的开发者,他们具有一定的项目经验,也能正常实现公司的业务需求,在对接的时候也会发现一些问题:比如基础不太扎实,提问的效率不高,疏于或者说不看技术文档等,很多都是上来直接说哪里哪里不行了,但是没做基本的对照分析,比如是否参考Demo代码,是否必现还是某个时间节点后才出现,提问题也没上下文,这些都比较典型,有的是惰性,也有出于自信;

  3. 在校生(准程序员)

    这部分用户也不少,因为很多人用Bmob来做外包和毕设项目,在笔者毕业的时候发现很多同学都用它来做毕设,而这部分也是出现问题最多的,一般在校生少数经历过企业项目的锻炼,学习能力和解决问题的方法论都不成型,职业素养也有待提高,经常出现基础很不扎实甚至问基础的java问题而非SDK的使用问题,甚至不经过百度和太多思考就直接抛出简单的编码问题和求助帮写代码;

  4. 一个典型的故事

    2017年底,一个在武汉企业用户反应说怕单纯的线上对接那边的程序员不太可能顺畅完成任务,因为那边的新项目要完全架设在Bmob云平台,不管是基础的数据存储,还是推送,支付,云逻辑,除了IM部分用融云其他都基于Bmob,就这样他们的Android和iOS工程师来到了广州驻点开发,而我也做为主要对接人员和他们做好数据库设计,SDK接入,功能开发,云逻辑功能开发直到上线的整个过程;

    对方的Android是一个86年的老哥,iOS是一个90后,在对接的时候发现iOS的基本是一些业务上的流程问题还有云逻辑js代码编写,沟通基本比较顺畅;而那个Android开发问题比较多,开发速度很慢,体现了典型的半路转行的非科班程序员的一些共性:功能开发速度慢,不会思考和定位问题,不知怎么提问,写代码完全没有自己的思路一大堆的意大利面条代码,没有任何的封装,不懂debug和IDE的快捷使用,不懂百度搜索解决问题,思维局限;经常出现问一些很基础的问题或貌似复杂实则不难处理的问题(如注册模块的协议文本说是复杂处理实际加个\n换行即可),一些问题比如说用图片加载库实现圆角头像也不会(实际在我演示给他操作的时候也是现学现用的),简单的二分法定位问题无法理解,无法讲业务上的概念用简单的数据结构实现等等,诸如此类都源于学习能力偏弱,而他也会好奇为什么你们的基础这么扎实,技术很6,解决问题很快呢?大龄转过来的程序员对开发debug也没有很好的理解,其实很多时候都是要短时间内学习并解决项目中的bug,加上他自身的思路很局限,教他的一些快捷编码操作等他转眼就忘按照老样子低效编码,一直恶性循环,有的时候甚至出现了和他讲解那么多为什么和怎么写之后其实还不如我自己写来的快多了的感受,而对方甚至出现过这些现成的参考代码你帮我cp写下可以吗的尴尬要求,也听到同事多次反(tu)馈(cao),但因为是想把该项目作为企业成功案例加上考虑他大龄转行过来也不容易就一直迁就,有一次周末陪他加班到把学生端的App的进度赶到95%后第二天他说项目不行了,运行出错,问他做了什么改动,一脸的无辜和不关我事的表情,只能直接把他代码拿来一点点调试。而iOS端的进度比他快很多,最多需要我去讲解SDK的一些进阶用法和建表思路,云逻辑代码编写等,到了2018年的3月,对方公司反映那边的Android端App实在无法体验,要委托给这边的实现,结果同事反馈代码十分混乱,一个个修复bug的速度还不如直接自己重新写,当然后面项目是上线了,不过这个过程确实揪心。在这个开发者在后续问我一些问题过程中,也基本都是很基础的在校生才会问的问题,无法独立解决问题。在最近和那边的iOS讨论马甲包提审的经验问题对方说到了他,换了新工作后问了iOS伙伴同事的Android开发,但是因为问的问题和态度急躁也使得对方不太情愿,其实很少有人耐心指导的,即使对方人很nice至少你也需要符合潜力好,学习能力强,主动积极,或者最少态度谦虚,可想而知他后面会走的辛苦一些如若没太多改观。

    能力

  5. 学习能力

    从刚才那个典型的故事也能知道学习能力的重要性了,而更进一步的是快速学习能力,特别是在业务技术日新月异下,很少有说能吃老本的技术,即使有,我也觉得是快速的学习和应变和解决问题的能力,特别是对那些以技术立命有志于精深于此的程序员,这些才是立身之本;不管是只做某个方向的开发(也会出现新技术风潮),还是在创业公司因为业务需要你需要从Android兼顾iOS开发或前端,怎么强调快速学习能力的重要性都不为过;而具备这样的能力,也无所谓岗位方向的调整和转岗,对你来说只是时间问题,切换过去还是类似的业务开发和见招拆招的解法套路,应对技术风潮的变化也更加从容(其实每次技术的大改变都能淘汰和过滤掉很多跟不上的程序员),其实这在一些企业的招人环节也会尤其看重,快速的学习能力意味着即使你没有相关业务领域(如电商,IM等)的从业经验,但出色的学习能力能让你短期内跟上队友,正如某知乎大V说”我并不需要你多么了解一个具体的技术如Ado.net,我希望的是即使你不清楚的前提下我和你说个几分钟你也能大致知道那是个什么东西和具体解决了什么问题“。

  6. 基本功(基础扎实)

    如果有较长远的技术规划和想把技术路走得更长远一些话,基本功是必须要思考和面对的话题;在出入行或许还没感觉基础扎实的必要性,因为这个阶段很多时候是在学习调用框架和SDK实现业务功能,加上简单的解决bug;但是如果随着项目复杂度提升遇到的一些较隐晦的bug或者做公共组件如SDK的开发,还是需要一些扎实的基本功的,或者说要深入理解一些三方库,那么你基本需要玩转java一些高阶api如反射泛型,自定义注解,编译时生成代码,动态代理等,这些在framework和热修复等中间件也有很好的体现和应用,而中小厂的开发,除了能灵活快速应对需求变化,自身不满足于现有层次愿对开源组件更深理解也基本是这样了;

    如果需要学习掌握更高阶的技术比如大厂做的一些性能相关的工作,那么就不仅仅需要语言层面的扎实了,就涉及到了科班通识学科的扎实,比如Android是基于Linux,那么涉及到一些异常捕获需要了解Linux的中断机制等,内存优化需要了解OS的内存分配策略等,这些也是目前笔者想学习和不太自信的,这些除了自身学习也最好能在一个大型App中有所运用(需要机缘)。

  7. 阅读代码的能力

    可以说作为程序员,大部分的时间除了做业务开发基本就是维护现有的代码和解决bug,很多时候入职也不太可能从0开始项目,都是基于现有的代码做开发,甚至需要修改和refactor现有代码,读代码需要理解现有的基本设计和意图,相当于本身功底也不能差,抓住主干不被无关代码noise干扰,所以平时可以多阅读一些优秀的开源组件的代码,类似母语的学习,看的多就有了不错的语感,当然必要的时候也可以辅助debug调试看程序的走向;

  8. 解决问题的能力

    程序员的日常两大活动便是功能开发和解决bug,而解决问题的经验技巧决定了我们能否快速分析定位和处理问题;

    笔者的理解是好点的情况是基于现有项目的代码去做bug的修复;不过笔者经历的大部分可能是这样:在资源有限(帮助有限,时间有限,只有apk包无源码)的情况下要分析问题(比如某个渠道包无法充值或闪退),那需要逆向看源码或抓包查看业务请求到了那个步骤和对应报文等;

    解决问题需要有自己的方法论(经验积累),比如是否有类似的解法,业务是否正确,当时间非常紧迫能否先折中规避再彻底解决,当出现貌似比较难解决的问题能否有更好的思路在别的角度分析解决(比如之前遇到的java代码不方便爬头条站点的信息流后改用chrome插件实现),特别是在复杂和多个问题下的处理,这也是目前笔者也在积累的部分,比如某个iOS包出现的问题在某个时间节点后出现,加载的是https链接,那么是和某个阶段新增的功能有关还是https有关;

    在一本书看到一个说法:”为什么有些程序员能很快找到问题所在,除了自身业务熟悉程度也和自身积累有关,积累的知识越广阔扎实越能提供更细致的可能并定位。”,所以,无他,需要持续积累;

  9. 技术之外的能力

    之所以提及这个,是因为笔者自己也遇到过;在项目开发中都是协同开发多见,虽说技术部分的能力是硬素质,但是一些软素质对项目是否能快速完成和交付也有影响,如沟通能力和主动性等,这些在大的团队中也会被重点衡量毕竟项目规模大,协同开发人员多;

  1. 可能其他的一些没提及,比如对技术的好奇心,写技术文档的能力等;
  2. 接触大量的开发者的同时也体会到了帮人解决问题的快感,也会反思作为程序员需要学会独立分析解决问题和自驱学习反思总结才不会太落后,重要是还是那句话:自勉