• Feeds

  • Archive for February, 2012


    技术工程师的能力与目标

    曾经有这样试验,随机选择一组对象进行工作的自评,几乎所有对象的自评分都在实际成绩的平均分以上。在工程师团队中也不例外,许多工程师有这样的困惑,自己觉得工作已经做得不错,但是上司好像察觉不到,甚至还对自己的工作吹毛求疵。如果有个合适参照标准,工程师或许就可以更好的对自己工作进行自评。

    管理者也同样面临类似困惑,在一个组织中,需要定期对团队中的成员进行考核及晋升,但是考核的标准是什么?小团队中主要取决于管理者的意志;大型组织中流程会更规范,但也存在考核者凭感觉来给被评估者打分的情况,或者是考核者心中的衡量标准千差万别。

    从工程师自我提升追求及职业规划的角度,情况会更复杂。每一个工程师都有不同的追求目标,孟岩有一篇很有影响力的《技术路线的选择重要但不具有决定性》,文中工程师的追求类型被描述成事业目标型、团队精英型、技术高手型、得过且过或养家糊口型四种。文中将“独特的个性知识经验组合”看做是工程师的核心竞争力,不过对于这个经验的组合不同人会有不同的理解。

    从团队或者企业的角度来看,主要从团队的贡献角度来评估技术工程师的成绩,就如同评估一个科学家的成看他看对人类的贡献类似。离开了环境,单纯评估技术没有意义。比如一个技术人员对Linux内核看得滚瓜烂熟,单就这一点并不能看到太大直接价值。

    但是在业界,知识点的重要性通常被放大了,业界也形成了一些非理性的氛围。工程师会努力学习某个技术(如C++语言)的方方面面,即使大部分场合只用到了其中小部分功能。技术管理者在招聘、考核、晋升等过程中也通常把知识点放在一个很重要的地位,面试题中会出现工作中并不常用的领域的各种知识点。

    这跟前几天某条关于大学教育的微博有异曲同工之妙,大学教育经历了全部是知识点的教育,慢慢意识到需要培养的能力不仅是知识点,而主要应是独立思考能力。

    技术人员追求的也不仅是知识点,而是在专业领域正确做事的方法及达成目标的能力。两个同时入职的员工,一段时间后技术好的那个就发展得好吗?还是有更好做事方法及能达成目标的人更容易得到认可?

    我认为一个好的工程师必要的能力

    设计能力

    设计能力参见前文技术评审中关于设计的描述,简要的说就是具备设计简洁、易于扩展及维护的功能及特性能力。

    需要补充一个设计方面的anti-pattern,选择合适的技术及架构,意味着不引入及增加不必要的抽象层或框架,并提供高质量、稳定、高效、安全的代码。不少能力还不错的人员有这个缺点,一个简单的项目,出于追求流行或者对于某项技术的崇拜心理,引入了复杂的技术或框架,对于个人来说确实提高了见识,增加了业内交流的资本,但是对于组织来说这种锻炼却是团队成效的噩梦,对于技术从业人员来说,不盲目引入不必要的高深技术来保证项目进展是一种基本的职业素养。

    此外设计中还有一个隐含的条件,就是选择的方案能相对减少开发周期,加快交付时间。也就是下一点介绍的。

    交付能力

    通俗的说就是不管发生了什么,都能按时交付。
    充分考虑自身技术能力、项目依赖、队员排期冲突、负面情绪、技术方案风险、未预知的技术障碍、需求变化等。
    具备为功能的设计做取舍的能力,但功能取舍并不以牺牲产品的核心愿景为前提。

    规范与协作

    在编码前能够完成模块或特性的清晰架构或设计文档,并保持在开发过程以及代码重构过程中文档的一致性。
    推动及促进团队的代码及设计规范,并确保执行过程中与规范的一致,并能根据实际情况对流程及规范提供优化建议。
    编写的代码通常当做团队的模板或者是最佳实践的设计模式。

    团队效率贡献

    有改善团队效率方面的贡献吗?比如做一个相似项目为何周期很长?为什么开发完成之后又花了比开发周期更长的时间调试或修改bug?
    推进代码复用,你的代码和工具其他小组或部门愿意用吗,准备让他们用吗?有推动让他们用吗?
    自动化体系来帮助提高测试、开发、debug、跟踪用户问题的效率
    能够用服务化的方法来解决异构、多版本问题
    有优化流程贡献?

    已经不是那个独行侠或个人技术英雄的时代了,融入团队,多考虑对团队的贡献,更容易得到成长。

    后记:职业发展方面话题比较大,不容易写好,本文也写得比较辛苦,改了两个晚上,暂不写类似话题。这也再次说明,当你有一个非常大的愿景(想当青年导师?),但系统能力还跟不上时,更应从小处着手。

    技术方案评审

    新年开始,大部分公司都在启动大量新功能的规划及设计、技术人员同时在设计对应实现方案、架构师或者技术主管则需要一天内穿梭在多个技术讨论中,评审并达成成熟稳定的设计方案。从架构师的角度来考虑,如何衡量一个技术方案的优劣呢?

    一、评审点

    从总体上讲,技术方案是衡量一个团队的开发成熟度重要一方面。技术设计是否围绕核心需求key features?模块依赖关系、兼容性是否得到充分清晰的描述及共识;设计上不同的方案是否得到了充分考虑比较?是否有正反的激烈的碰撞还是行政上的领导说了算?另外代码实现是否正确执行设计,还是代码实现边走边看,与设计方案基本脱节?

    从细节上来看,在软件企业内经常有不同形式的方案review,架构师在做review时候需要要考察哪些环节?从互联网系统设计的角度,总结到以下几点。

    简洁及可维护性
    从工程角度来看,避免难懂的方案。技术方案尽量象PPT那样,越傻瓜的方案越有生命力。当然简洁的同时也要满足后续条件。

    性能、健壮性及可扩展性
    互联网项目唯快不破,性能是立根之本。我们需要为健壮及性能留有一定扩展余地。

    避免过度设计
    Donald Knuth说过“过早优化是万恶之源(premature optimization is the root of all evil)”,不少架构师也牢记于心。但是在实际操作上,这一点和上一点所说扩展性直接冲突,比如
    保守派:质疑在一些环节增加可扩展性,需要多花很多精力(比如30%),但增加的扩展能力未必能用上。
    激进派:质疑如果不增加一定扩展能力,当需求稍微发生变化,方案需要全盘推翻。
    可扩展性及过度设计的矛盾是否如薛定谔的猫那样,需要打开盒子那一刻才知道结果?还是架构师可以根据经验及环境去取舍,从我的观点来看,“make appropriate design tradeoff”是衡量架构师能力的首要指标。

    Case Study
    拿年前比较热门的12306系统来举例,如需做一个方案实现其中的余票查询模块,假设设计如下

    12306查询模块设计方案

    需求
    1、能够承载峰值查询为10万次/秒的请求
    2、余票信息能容忍一定程度和实际系统不一致,但是滞后不能超过5秒
    附加需求:为了此虚拟项目更具有可比性及易于理解,设计方案必须全采用开源技术实现,不修改相关服务器源码,并采用普通廉价服务器部署。

    技术难点
    1、峰值处理能力,需要用最小的成本解决
    2、数据需要5秒内动态更新的问题,需要采用合适的方案

    技术选型
    采用nginx, MySQL, varnish, memcached来实现
    假设nginx+远程cache处理能力是2万次/秒;varnish在大部分本地cache命中情况下处理能力是3万次/秒;

    方案一
    采用cache直接查询的方式

    方案二
    采用七层反向代理增加cache的方式

    数据更新的方案设计
    需要将订票系统中的实时变化反映到查询系统中
    方案一:PULL

    方案二:PUSH

    使用上面的方案评审方法来看,方案有什么问题呢?

    二、方案文档

    另外再说下技术方案的文档要求。一个团队如果没有形成技术方案的规范,交付的方案通常是五花八门的,有word、visio、邮件,mm图、ppt、PDF、纯文本…… 怎样才算一份好的设计文档?

    核心需求及技术难点
    很多技术方案第一段就直奔主题,比如展示模块图或者存储结构,这会让阅读者一头雾水,先告诉阅读对象“我们究竟要解决什么技术问题”。


    一张A4纸上密密麻麻写满同一字号文字的方案令人生畏,“一图胜千言”,用txt、一封邮件、或者纯文字的word通常情况下较难得到理解

    文字、关键字
    方便本地或者文档服务器全文检索,文档支持版本管理。
    一个团队运作一年以上之后,文档数可能成百上千,需要通过关键字来快速查询,需要支持版本管理的文档服务器及仓库。而仅靠设计方发一封邮件来提供给大家技术方案很难形成技术积累。

    便于修改
    技术方案及设计文档需要方便团队每一个成员更新,技术方案在代码实现时会有设计的改进及微调,这些需要能随时方便的更新到设计文档上,大部分团队存在设计文档与代码实现脱节的情况。而用一个图片或者pdf的来提供技术方案的更是让执行人员更新方案无处下手。

    三、扩展作业

    在文章结束之前,顺便再出一个今天随便想到的facebook中的like功能作为扩展训练题

    需求

    • 可以对一个对象(一条feed、文章、或者url)进行like操作
    • 需要看到一个对象的like总数
    • 可以看到一个对象的like用户列表,优先显示我的好友列表(social list)。
    • 数据量:每天新增的like对象数为1千万,每秒like计数器查询量及social user list均为30万次/秒。

    假设现有系统的存储结构(MySQL)为
    friends表, from_uid + to_uid 为联合主键
    (from_uid bigint,
    to_uid bigint,
    ctime timestamp)
    feed表, feed_id + like_uid 为联合主键
    (feed_id bigint,
    like_uid bigint,
    ctime timestamp);

    假设以上存储是单表结构,请问如何设计like技术方案?如何评判你的like方案的优劣?

    广告:新年开始,新浪微博技术团队也正在招兵买马,对以上内容感兴趣的技术人才欢迎投递简历,层次不限,从架构师到有一定基础的Java及PHP工程师都可,联系方式见blog右方。

    谈技术团队目标

    技术主管新年想得最多的一件事必定是如何比上一年做得更好。宏大的目标设定每个团队都会做,谈几个不引人注意的小问题。

    1、主动与被动

    见过一些技术团队将计划定义为“按时完成需求”,需求驱动并没有什么不对,但是研发工作仅考虑被动需求的话是很难做好。

    • 之前完成的许多需求有什么共性?
    • 延误的项目有哪些原因?
    • 经常出问题/bug/故障的项目/功能/模块是哪些?
    • 代码、关键路径、架构中有哪些已知的缺陷?
    • 用户不容易发现,但是已经存在的问题有哪些?

    围绕以上类似问题出发,找出在研发上需要做哪些主动改进。

    2、关注效率提升

    大部分团队会非常关注如按时交付等直接目标,当目标遇到障碍时,技术主管通常就会用直接的方法(如加班)来解决。但是考虑长远,有很多间接的手段能更好改善效率。

    • 是否存在培训体系,针对专业知识、业务知识进行专项培训?
    • 针对新人是否有进阶的各层次引导培训?
    • 团队的文档建设如何,是否经常要阅读前人代码才能维护?
    • 某个地方经常一修改就出bug,是否有机制保证及时重构?
    • 是否有清晰的开发流程、项目流程、发布流程,还是依赖团队人员的经验或智慧?
    • 开发流程中是否有方法形成共识的需求,技术设计是否有review习惯?

    如果只看到直接目标或短期收益,可能一年之后技术主管还在疲于奔命,感慨有做不完的事情并埋怨团队效率低。

    3、量化体系及工具

    当团队较小时候,依靠team leader领头羊作用以及团队成员的内驱力就可以将目标完成得不错。当团队进一步扩大,尽量建立量化的体系及工具,比如目标“将存储时间缩短30%”,需要考虑是否有现成的方法来测量、是否有日常的采样数据等,而不能依靠一时的临时对比。业务的数据每个公司都会第一时间建设,但是衡量软件性能及效率的工具及数据通常未纳入到日常化建设。

    4、持之以恒

    建设一个高效的研发团队无法一撮而就,让一个10人以上的技术团队形成合力,保持持久的开发效率提升及高质量交付,需要长年的建设及努力。

    一年之计在于春。