一个引子

码农和程序员有什么区别?

我认为,码农可以做一些简单的编码工作:实现某个脚本,拼装某条 hql,“写完”某个函数。往往有一定语言知识,有一定的编码经验;但是很少对需求细致分析,缺乏“恰当”意识。他可能会用一条 sql 完成整个功能,也可能用一个 for 循环遍历所有接口,甚至为了某个不重要的 update 加锁、加事务…… “为了目的,不择手段”,而且并不确切目的是什么。

而程序员,他知道自己要做什么。可以把一个函数写的性能优良,可以把一个模块设计的很“恰当”。他熟悉 MVC, 熟悉设计模式,可以让他的模块整洁、完美。甚至,可以创造性的解决一些产品问题,让代码充满灵性。但是,往往全局观不足。

那么全局意识指的是什么呢,我们应该怎样培养我们的全局意识?

肯定不是 pm 让我做什么,我只要写代码把它实现就好了。而是要首先明确为什么要做这个,做这些的价值是什么。

我们有义务帮助产品找到最恰当的解决方案,然后用合理的方式把方案嵌入到代码中。同时,要让保证架构活力,要可以快速定位bug、解决bug。清楚上线流程,要保证上线后不会产生任何的消极影响。

一个合格的工程师,可以让产品需求平稳地落地。那么我们应该怎样做到呢?我认为可以从以下几点出发。

1. 明确需求细节,少做无用功、廉价功

我们应该首先应该明确产品需求是什么,但更重要的是为什么。产品为什么要这么做?预期的目标是什么?哪些数据表明这些目标达成了?如何去收集这些指标?

然后,去判断需要哪些人配合,高优先级去协调资源。如果判断人力成本过高,或者收益有限,可以说服产品延后部分需求的实现。集中精力做最重要的事情,少做无用功。同时,积累工作经验、数据经验,锻炼自己对“性价比”的敏感性,让自己的判断变得客观、有效、权威。

2.代码的执行可视化

在开始设计功能前,应该先考虑怎么去做监控。不能让功能迷迷糊糊地在线上跑着,“它应该是对的吧”……越实时的反馈,越可以早得发现问题,越可以早得为项目止损。同时也是对工作的负责,更是对自己汗水的负责:谁也不想自己辛勤写出来的代码,直到下线那天才发现一直没有运行“对过”。

  • 哪些指标,证明功能是 ok 的
  • 哪些报警,证明这是个 bug,那里肯定挂了
  • 哪些指标,证明这个需求是有价值的 (比如:某个功能数据过低,此功能的后续迭代就应该适当降低优先级)

3.出现反馈如何应对,出现 bug 如何修复

产品的 feature 不可能让所有人都喜欢,甚至有时为了产品调性会做些对用户打压的事情。这样的功能如何让用户接受?如果不接受,产品应该如何去引导;技术应该如何辅助产品定位问题。

举个例子,首页 feed 会过滤掉用户屏蔽的条目。如果用户屏蔽了话题 A, 绑定了 A 话题的条目不会分发给用户。这是一个很合理的产品 feature, 但是用户会经常误以为对 XX 内容限流。运营就会要求我们查 bug。像这种需求,我们要做的不只是开发功能,更应该考虑后期如何应对反馈,提高响应效率。

某个关键功能出了 bug。我们应该如何跟用户解释?应该如何修复数据?修复如何快速?那么我们可能要考虑,我们要不要准备修复脚本,我们是不是需要操作幂等,数据操作该不该记录审计 log……

4.确保代码没有腐化架构

依照上面两步,我们意识到了要对业务指标可视化实时监控,要考虑问题的应急方案。然后,就可以着手设计我们的功能框架。所谓的实现需求,不是写个 function 把逻辑写完就行,更不是一个 sql 把数据丢给用户。所谓的架构,就是为了完成一套完整的功能,合理组合的多个模块。要让你的代码更好的被人看懂,要在恰当的地方完成业务监控,要用恰当的逻辑为应急提供方便。

如果发现现有的架构不能恰当的融入你的需求,千万别打个补丁硬推上去。“逻辑”谁都能写完,但是要让别人觉得,这块代码本来就应该在这里。衡量代码质量的唯一有效标准:WTF/min —— 出自《Clean Code》。

我们应该努力拽着自己的项目,让它离“屎”远一点;而不是增加一坨。写代码时,应该考虑的是怎么用,别人怎么读,而不是我怎么写!只对作者友好的代码绝对是垃圾。面向工程,面向合作。要让用的人舒服,让用的人心理成本低。

5.邀请大家进行 CodeReview

本着一个工程师的素养,我们应该努力拽着自己的项目,让它保证架构的清洁;但是,这只是一厢情愿的。在代码真正推上线前,我们需要让更多的人 code review,以求达成共识。

我的经验是,如果涉及架构调整,我会先提交一个初版,让一些有经验的工程师帮忙评审架构设计。这个阶段我们千万不要追求代码完成度、单测覆盖率。因为很可能架构设计不合理,可能会引起大量的返工,部分工作可能会直接作废。所以,我认为一个合理的 CodeReview 可以分为四步:

  1. 按需求调整代码架构,尽早提交框架 diff。评审者主要关注:改动是否污染了架构,调整后的架构是否易于新人学习,新增模块是否容易 debug (比如,方便构造 bug 现场)
  2. 填充架构细节,“优雅”地实现各模块逻辑。评审者主要关注:功能拆分是否清晰,类是否抽象合理、是否符合语法习惯 (如python, 是否可以适当使用列表表达式、lambda)
  3. 确认各模块逻辑无异常、无 bad case。评审者主要关注:功能是否完全覆盖单元测试、是否已经完成了联调、是否进行了完善的功能测试
  4. 确保代码细节。评审者主要关注:是否合理的捕捉了第三方工具的异常,是否有合理的功能降级、模块降级,循环是否合理(严防死循环),变量命名是否表义、变量作用域是否过大……

所以,我认为 code review 不是一次性的。如果你突然收到了一个 100+ 文件变动的 merge request,那作者肯定只是想让你给他 approve:停留在形式上的 code review,至多只是因为作者想找个人“共同背锅”。合理的 code review 应该把握大框,逐步细化,渐入佳境。

其实,一步步按着上面的思路来,每一步都有特定的焦点,并不会花费大家太多时间。

6.确认好依赖,让改动平滑上线

相信经过上面严格的 review, 我们可以拿到一份大家具有共识的优良代码。但是,代码优良不代表可以部署上线。除非你在写 print \u0026quot;hello world\u0026quot;, 否则,你的功能与各种上下游服务势必会有千丝万缕的联系。我们必须在上线前,确认好所有的依赖不会阻塞我们。

首先我们要检查自身是否有先验逻辑未就绪。比如:知乎首页需要新增加一种卡片样式。要先确保版本兼容逻辑已上线,否则旧的客户端收到不识别的卡片可能会 crash。再确保数据库数据初始化,数据库里没东西上线没有意义。

其次要检查下游逻辑是否已经就绪。下游服务功能是否正常上线,是否能承担我们的请求压力;数据表 schema 是否变动、是否已上线,数据库容量是否足够,数据库是否能承受压力;相应缓存是否应该预热……

然后,需要通知我们的上游服务。我们的改动是否不兼容,是否会引发上游调用出错;我们的改动是否影响了性能,是否需要上游调整 timeout……

7.最小化验证尽量止损

前期做足了准备,大家足够警惕地关注着自己的指标变动。然后,我们就可以上线了。

但是,正因为各种指标可能会出现难以预期的变化,我们需要逐步扩大功能的影响范围。比如,先用办公室环境,然后放量给 10%、20% …… 的用户,同时观察指标变化。

当然我们应该“事先”明确应该观察哪些指标。比如,接口的 QPS、P95、5xx;依赖我的服务是否正常,我依赖的服务指标是否异常;存储服务、业务指标是否正常… 发现异常及时回滚。

小结就是:

  • 在上线前,先想好自己应该关注哪些指标
  • 上线过程,注视指标,逐步放量
  • 遇到任何异常、疑似异常,及时回滚

尾声

代码编写其实没有难度。哪怕是个小白,在培训班学呆半个月,就可以实现个小功能:打印个 hello world, 转置个数组,甚至实现个快排……面试宝典、leetcode 可以帮你顺利的通过面试。

但面试通过只是说明面试官觉得我们不错,不是证明我们可以胜任之后的工作。常言道,“面试造火箭、工作拧螺丝”,面试题目与工作实战还是有相当大的差别的。不过,只要用心体味,你会发现,实际上工作要比面试的“火箭”复杂度更高。工作造的“火箭”与面试的“火箭”不在一个维度,工作的“火箭”是在帮我们从码农演变成工程师。

而工程师素养,才是衡量我们能不能在这个行业走深走远的关键。

关于合格工程师素养的一些思考相关推荐

  1. 关于测试工程师的职业发展思考

    关于测试工程师的职业发展思考 2017年,因华为裁员.中兴员工坠亡等事件,"IT吃青春饭","中年危机"-一词又在网络上掀起了一股巨浪.那些面临即将走上IT工作 ...

  2. 软件测试工程师的一次思考

    软件测试工程师的一次思考 一个从事软件测试8年的工程师的感悟! 第一点:时间永远不应该限制你的能力 计算机专业大学毕业后,做了3年硬件,后一个偶然的机会,踏入了软件测试的大门,那个时候,是2010的一 ...

  3. 奔向三张,不破不立:一个iOS开发工程师的职业规划思考(转自iOSer 逆,以资激励)

    大前天下午快下班那会儿,跟念茜聊了一下各自的工作现状,发现她现在碰到的一些职业规划上的困惑,跟我在一年多前的情况非常相似.而我经过一年多来的不断思考和调整,已经基本明确了自己的职业规划,发展的方向变得 ...

  4. 奔向三张,不破不立:一个iOS开发工程师的职业规划思考

    大前天下午快下班那会儿,跟念茜聊了一下各自的工作现状,发现她现在碰到的一些职业规划上的困惑,跟我在一年多前的情况非常相似.而我经过一年多来的不断思考和调整,已经基本明确了自己的职业规划,发展的方向变得 ...

  5. 关于工程师晋升答辩的思考

    不同的互联网公司里面,研发工程师的晋升方式也许各异,但通常会有答辩这个环节,下面列举下我关于工程师答辩的思考: 临场发挥   1. PPT的制作      a. 开篇介绍时,避免"只见树木, ...

  6. 诸葛越:关于算法工程师职业发展的思考

    <职业发展论坛>专栏·第01篇 整理 | 吴雪松 校对 | 王大川 来自:DataFunTalk 导读:近年来人工智能技术取得了巨大的突破,应用到工业界的场景也越来越多,吸引了大量的人才涌 ...

  7. 写给迷茫的你:九年京东测试工程师的职业规划思考!

    一.软件测试起源 网上有一些经典的软件事故,大家感兴趣可以自己搜索一下,我搜了几个列举如下: 简单总结:软件出现缺陷(BUG)导致经济或其他损失,因此有了软件测试. 由此可知软件测试目的:发现缺陷(问 ...

  8. Google资深工程师讲述谷歌如何思考测试

    以下为作者观点: 测试一直是编程的一部分.事实上,当你第一次编写计算机程序时,几乎肯定会抛出一些样本数据,看看它的表现是否符合你的预期.自21世纪初以来,为了应对现代软件系统的规模和复杂性,软件行业的 ...

  9. 一名前端工程师自检清单与思考(来吧,干完这套清单年薪30不是梦)

    一份不想成为劝退清单的劝退清单 一.JavaScript基础 变量和类型 1.JavaScript规定了几种语言类型 2.JavaScript对象的底层数据结构是什么 3.Symbol类型在实际开发中 ...

  10. 干货 | AI 工程师必读,从实践的角度解析一名合格的AI工程师是怎样炼成的

    从年初起,几家国际大厂的开发者大会,无论是微软Build.Facebook F8还是稍后的Google I/O,莫不把"AI优先"的大旗扯上云霄. 如果这一波AI大潮只是空喊几句口 ...

最新文章

  1. timesten 修改最大连接数
  2. PLUS | 包含蛋白质特异性的新型预训练方案
  3. flash大作业一分钟源文件_「百树云课堂」一写作业就像被雷劈,是什么“病”?...
  4. 最新桌面操作系统份额统计:Windows占比91.59%
  5. node.js(八 --- express)
  6. java .class 实例对象_通过Class类获取对象(实例讲解)
  7. 什么时候需要用到RCC_APB2Periph_AFIO
  8. 书单 电影单 电视剧单
  9. linux notifier chains机制
  10. GANs奇思妙想TOP10榜单
  11. 解决word2019中求和符号上下标被强制挪到右边的问题
  12. 在Java中打印金字塔图案
  13. R语言使用wilcox.test函数执行wilcox符号秩检验获取总体中位数(median)的置信区间(默认输出结果包括95%置信水平的置信区间)
  14. 记一次 【Unknown thread id: XXX】 的排查
  15. 猫喜欢吃鱼,可猫不会游泳
  16. JAVA一些实例实战
  17. js 毫秒 微秒 转为 时分秒
  18. hello,bili
  19. Hexo 博客快速整合公众号导流工具,不用互推也能实现粉丝躺增!
  20. 阿里云服务器被检测到有wa kuang程序

热门文章

  1. 6迁移-企业级 Hyper-v 群集部署实验方案
  2. c语言删除文件remove_「Python」 - 文件基本操作
  3. SQL语句统计每天、每月、每年、今天、昨天、本周、上周的数据
  4. [C# 网络编程系列]:TCP编程
  5. android lottie字体json,Android Lottie集成及基本用法
  6. hexo 环境变量_优雅的博客框架,快速、简洁、高效且主题丰富——Hexo
  7. malformed utf-8 characters, possibly incorrectly encoded
  8. python datetime和unix时间戳之间相互转换
  9. 最近尝试移植了一下java.awt/javax.swing
  10. 问题:安卓手机插入OTG摄像头时,如何禁用摄像头自带的MIC?