序2 用管理的方式做技术
- 1)队员工作没有自己做得好,花时间去沟通还不如自己去做。2)感觉自己的技术在退化,长期不写代码觉得自己没有价值。3)发现自己不懂的东西越来越多,觉得把管理做好不太容易。
序4 技术领导之路
我则认为,如果你有能力把技术相关的资源有效地组织起来并完成一件有价值的事情,例如,发布一款产品,做一个项目,那么你就是技术领导者,或者说,你具备了一定的技术领导力。
简单来说,技术领导可能是个管理岗位,也可能不是,不重要。重要的是你要利用技术资源和团队资源把事情做成。
优秀的技术领导会超越这些东西,他们关注的内容不再是某个具体的技术和实现,而是事情。让正确的事情,持续发生才是最重要的。
技术,技术,技术
一个技术领导,更多是通过对技术领域的探求打磨自己的技术敏感度和技术决策力。
如何用好当下的技术解决现实中的问题,什么阶段引入什么技术,什么时候重构,什么时候重写,如何利用技术驱动产品,如何构建技术平台……这些都是技术领导需要思考并确定的问题,这些都将依托你强大的技术背景
事实上,如果你选对了人,大部分看起来困难的事,都可以解决。
很多时候,团队的人跑过来问你怎么办,只是希望你给他们信心,而不是指望你去给他们写代码。
程序员对技术的渴求和敏感度,就像枝桠对阳光和雨露一样渴望和迫不及待,只要等,大部分时候,他们都能找到出口。当然,真的遇到困难搞不定了,协调资源或自己提刀上阵就是了。
你的工作是什么呢,除了技术,还需要保护团队中的工程师不被打扰,在各方面给他们支持,帮助他们能顺利完成任务。同时你还需要在重大的方向上输出影响力,做决策,定计划,这也意味着,如果决策是错误的,需要你来承担责任。而有了荣誉的时候,你要退下来,让给团队里那些优秀的人。这样的团队,才能无往不胜!
人才都会有很多种,有的是匠人型,有的是天才型,他们有的人步伐齐整,一步一个脚印,行走就像时间本身一样流畅,唰,唰,不可阻挡。有的人似乎原地不动,呆呆思考,但是瞬间会来个百米冲刺,把所有人都落在身后。无论是行走,还是奔跑,他们都需要合适的道路和轨迹。设计好这样的通道,帮助这些人才成长,他们自然会做出成就。
前言
技术管理岗位不容易做,既要保证自己的技术说服力,又要经常上一线工作,还要从管理上给予团队支撑
技术管理人员很多时候就是一个小号的CTO,如果需要自己决定产品方向、销售,那就是个小号的CEO,所以技术领域的综合能力也是你的必备能力。
人应该学会回馈社会,技术分享也是回馈社会的一种方式,而以写作方式进行技术分享是我所能最大程度回馈社会的一种途径。
我的妻子美丽、细心、博学,虽然偶尔不那么温柔,但是我很爱她。
第1章 技术管理工作
什么是技术管理,为什么这么难做。 ❑ 技术管理包含哪些方面。 ❑ 如何做一名合格的团队领导者。 ❑ 团队领导者应该具备哪些品质。 ❑ 带领技术团队的心得分享。 ❑ 个人职业发展需注意的事项。
硬件容易模仿,软件则需要自上而下的认知
个人的高效能不可怕,团队的高效能才可怕,当团队中每个人的潜力都被发掘出来,能力的集合才是巨大的,才能所向披靡。
随着社会的进步、人类思维的开放、经济水平的提升,被管理者(工程师们)逐渐从单纯为了解决物质矛盾转化为追求工作的归属感、参与感、技术尊重感,他们逐渐对跟着谁一起工作、采用哪种工作方式、解决了什么样的技术问题、做出了什么样的产品感兴趣,而不是仅仅满足于金钱的多少。
我们每位技术团队管理者,也正在像书一样被摆放在被管理者面前,如果别人懒得翻你,就证明你不能给予他们指导,他们没有归属感,最终都会匆匆离职。
如果是一家成熟的科技公司,它应该从多个维度评审技术团队管理者的工作过程和成绩,而不是采用单一化规则进行评判。
❑ 深入理解一门或多门编程语言 ❑ 深入理解多种流行的框架 ❑ 系统架构能力强,拥有复杂系统的设计经验 ❑ 积极跟随开源社区 ❑ 积极了解业界技术发展 ❑ 沟通能力强、情商高 ❑ 有产品意识,不是技术迷 ❑ 会带人,服从领导,责任心强 ❑ 会写专利 ❑ 再会点别的更好 ❑ 随叫随到、工资不高
一家企业能够生存,一定是业务开展得不错,作为技术团队管理者我们需要做到技术与业务的融合,需要保证我们的付出可以为企业带来长久的利润。只有成为“技术的业务派,业务的技术派”,才能让技术引领业务,并创造价值。这其实也是技术管理者成熟的标志。
以电商企业为例,如果技术团队的定位仅仅是为了完成业务部门提出的需求,那么对公司的价值是不大的,技术团队的定位应该是“技术引领业务”。首先,技术人员要成为业务专家,能够通过系统性的思考,规划出跟企业管理思想高度一致的电商系统。
一位管理者最重要的是给团队指明方向,包括技术方向和业务方向,还有个人成长方向。与下属相比,领导者的优势不只在于他的专业能力,还在于他的眼光和胸怀。既然选择做技术管理,你就要有成就他人的心胸,同时还要有超出一般人的眼界,能够给予团队正确的方向。同时,要保持对技术的兴趣,多关注新技术的发展,否则你很难在重大的技术决策上做出正确的决定。
“走向成熟就是独立得更彻底而又联系得更紧密。” —— 霍夫曼·斯塔尔
技术团队内部有一些员工,也许他们不善言辞,但交付的任务,他们一定会尽全力完成,遇到不懂的地方也会主动请示、沟通,个人姿态摆得很低,这样的员工内心非常成熟,知道如何做事、体谅上级、努力工作,而不是把精力放在正经工作以外的地方。他们是团队的中坚力量,是不可或缺的成员。我认为衡量一个团队的凝聚力是否强大,看看这类员工的占比就知道了,缺少这类员工的团队一定不会有什么了不起的成绩。
“我认为克服恐惧最好的办法理应是:面对内心所恐惧的事情,勇往直前地去做,直到成功为止。” —— 罗斯福
作为团队负责人,我们也应该有硬汉本色,不能惧怕外在的威胁。团队成员都在看着你,你决不能懦弱,要勇敢。
在电视剧《长沙保卫战》中有一段对话,参谋长对薛岳将军说:“你若下地狱,我绝不上天堂。”这也是我在团队遇到严重挑战的时候,对所有成员说的第一句话。想做成事情,你或者你的核心下属,必须勇于站出来。
我对团队的技术要求一直都是:“我们输出或者呈现给别人的技术能力,需要且必须是公司内部的技术权威之一,说是之一,是因为不能否定公司内部其他部门的技术能力。我们必须让别人知道我们是专家,我们团队很牛。如果被别人列举出我们团队技术不尽人意之处,我会认为这是对我人格的侮辱,只要我是这个团队的领导,我决不允许这种情况发生”。
你们要像种子一样,到最需要的地方去,生根、发芽、开花、结果,再成片开成花海。部分勇敢的人,要到最艰苦的地方去快速成长。” —— 任正非,华为总裁
我认识一个男生。在高考那年的春节,客厅里亲戚在搓麻将,房子外鞭炮声此起彼伏,他坐在书桌前温习功课,亲戚说他太用功、太自觉了。工作以后去外地出差,他身边永远带着技术书,同屋的同事要看电视,没有地方可以看书,他便走进刚洗完澡的浴室,坐在潮湿的空气中看别人的代码,惹得同事说你也太认真了。现在,这个男生步入了男人的年纪,出了三本书,提交了近20项发明专利,为各类技术杂志写了50多篇文章,工作中也拿到了很多奖项。这个男生就是我,周明耀。高中时代曾经被物理老师认为脑子不太聪明、为人倒是挺厚道的我,依靠着自己的努力,逐渐在技术圈有了知名度,得到了技术人员的认可,谢谢诸位恩师、良友。
马尔科姆·格拉德威尔(Malcolm Gladwell)在《异类》中提出的一万小时定律:要成为某个领域的专家,需要一万个小时的训练。按比例计算就是:如果每天工作八个小时,一周工作五天,那么成为一个领域的专家至少需要五年。
学习一个东西如果只是能听懂,还不算学会;如果能够按照所学去执行,也才学会了一半;如果能够把所学的东西用自己的语言表达出来,让别人听懂,这才算差不多学会了。
如果一开始我仅仅去改变我自己,然后作为一个榜样,我可能改变我的家庭;在家人的帮助和鼓励下,我可能为国家做一些事情。然后谁知道呢?我甚至可能改变这个世界。
我想说的是,你在做这些决定之前,有没有做足充分的技术调研、产品调研工作,能不能尽量详细地说清楚已有框架、产品的实现原理、优缺点、是否适用于你的产品场景等,这些都是前期技术调研的工作,也是体现我们脚踏实地做事的一个环节。
如果不吸取失败的教训,那么失败就仅仅是失败。
一个人的逻辑能力属于软实力,它是决定你是否可以承担团队领导职责的关键因素。
举事以为人者,众助之;举事以自为者,众去之。
成为领袖的人,都是从小事做起的,不要好高骛远。
我可能会不赞成你的看法,但是我尊重并捍卫你说话的权利。 —— 伏尔泰
我们需要倡导“开放、共享、追求极致”的团队文化。人才是我们最大的财富,所以要建设以人为本的团队文化,创造出沟通顺畅、敢于挑战、喜欢创新的团队氛围。
作为一个管理者,你的重点应该首先在于创建出有良好化学反应的、能把事情做好的团队,然后再考虑分配什么任务给他们。好的团队,不仅可以很好地协同工作,还能彼此互相学习。
漫无止境地追求奢华,远不如俭朴生活带给你幸福和快乐。
“有了真诚,才会有虚心,有了虚心,才肯丢开自己去了解别人,也才能放下虚伪的自尊心去了解自己。建筑在了解自己了解别人上面的爱,才不是盲目的爱。”
“一个人只要去行动,去坚持,去积累,就会在翻山越岭后看到胜利的曙光,会享受到成果以复利方式增长,会收获时间的玫瑰。” —— 沃伦·巴菲特
一个人一生如果想要获得过人的成就,就注定与读书和终生学习形影不离。
复利(Compounded Interest)是这个世界上的第八大奇迹。
这实质上和年龄无关。
记住,一个人只有严于律己,长年累月专注做好一件事情,并且坚持终生读书、学习,才能享有并保持随之而来的成功、荣誉和认可。
通常,最好的方式是在每一天早晨花上一定的时间来规划一天的安排。
绝对不可忽视你团队的人,并始终要坚持以人为本。
不是我闲暇时间多,而是我要给自己不断输出技术成果的目标和压力,进而不断提升自己的技术能力。
当你觉得每天只有50%时间可以做技术的时候,但你还是能够紧跟技术,甚至比你的大多数下属都了解细节的时候,你就可以尝试给自己加上技术管理的工作量了。
❑ 第五等工程师,能够独立设计和实现一项功能的人。这是对工程师的基本要求。❑ 第四等工程师需要有点产品头脑,也就是说他们在做一件事之前,要知道所做出来的东西是否有用、易用,是否便于维护,是否性能稳定,等等。除了要具备产品设计方面的基本知识,还要具有一定的领导才能,能从头到尾负责一个产品的生命周期。这在很多硅谷的公司里是一个高级工程师所应有的基本素质。❑ 第三等工程师,可以做出行业里最好的产品。他们与第四等工程师有着质的差别,这不仅反映在技术水平、对市场的了解、对用户新的了解以及组织能力等诸方面,而且也反映在悟性的差异上。❑ 第二等工程师是那些可以给世界带来惊喜的人,他们在其工作的原创性以及对世界的影响力上和后面三等有巨大差别,例如扎克伯格。❑ 第一等工程师是开创一个全新行业的人,这些工程师不仅在技术和产品等各个方面与第二等工程师有了质的差别,而且在经验和管理上也是好手,他们通常也是企业家,并通过自己的产品改变了世界。这一类人常常是可遇而不可求的,例如冯·诺依曼。
要么你聪明,会交际,懂政治,被人认可;要么你做出成绩,贡献巨大,被认可。
最好的领导,思路敏捷而清晰,做事务实而高效,永远没有废话,永远雷厉风行
评判一个管理者的好坏,从来不是看测验的民意,而是看输出的成绩。良好的干群关系和群众基础,有助于达到目的,但却不是最终目标。
不断地调整自己的工作方式,不断地加强自己各方面的能力,特别是改正自己的弱点,这些才是你应该去关注和为之努力的。
这条曲线说明从业者整个职业生涯一直在不断地学习、在不断地增强自己的综合能力、不断地自我积极调整以适应企业需求。
CTO和技术VP,两者应该是合力开发产品,而不是谁领导谁的关系。
杰出的程序员和一般的程序员的巨大差距在于需要多久你可以把自己的想法转变为代码。
第2章 团队建设、人员管理
爱因斯坦说过:“一个人只有以他全部的力量和精神致力于某一事业时,才能成为一个真正的大师。因此,只有全力以赴才能精通。”
我在职业生涯中投篮失败9000余次,输掉了300场比赛,有26场比赛,我被委以投出致胜球的重任,却没能命中。我不断地遭遇失败,而这恰恰是我取得成功的原因。——迈克尔·乔丹
不懂的东西我学学就会了,没什么大不了的。
《错不在我》的作者Carol Tavris认为:“认知失调是我们在自我认知(我是聪明、善良的,我坚信这是真的)受到事实挑战时所产生的感受,表示我们做了不聪明的、伤害到其他人的事,证明我们之前的想法是错的。”
敢于承认错误,并积极地弥补错误所造成的损失,是一种非常可贵的精神,值得我们大力称赞
“一流人才招聘一流人才,二流人才招聘三流人才。”——史蒂夫·乔布斯
明确我们当前是需要开发经验,还是需要对技术有钻研热情的人,即你是需要:❑ 一个可以领导整个团队开展各种实际工作的程序员?❑ 一个可以找出产品里隐蔽难寻的设计缺陷的程序员?❑ 一个具备大局意识、能预想到需求可以如何分解为模块和组件的设计师?❑ 一个能主动行动、能很好地配合管理层的工程师?还是需要:❑ 在短时间内可以编写数千行代码?❑ 能够快速开发出对客户非常重要的原型系统?❑ 能快速领会业务流程,围绕根本需求设计产品。
大家要记住,招聘一位员工,从一开始就已经使用了公司的资源,HR招聘专员、面试官、会议室、领导、HR薪酬专员、HR合同专员等,这一系列的人员、物资都是公司的资源,所以一定要确保招聘策略准确无误,避免出现对的人看到我们错误的岗位描述。
STAR是SITUATION(背景)、TASK(任务)、ACTION(行动)和RESULT(结果)四个英文单词的首字母组合。
知识、经验、技能、工作风格、性格特点
❑ 背景(SITUATION):通过不断提出与工作业绩有关的背景问题,可以全面了解该应聘者获得优秀业绩的前提因素,从而获知所取得的业绩有多少是与应聘者个人有直接关联的,有多少是与市场的状况、行业的特点有关的。❑ 任务(TASK):每项任务的具体内容是什么。通过这些可以了解应聘者的工作经历和经验,以确定他所从事的工作与获得的经验是否适合现在的职位。❑ 行动(ACTION):了解他是如何完成工作的,都采取了哪些行动,所采取的行动是如何帮助他完成工作的。通过这些,可以进一步了解他的工作方式、思维方式和行为方式。❑ 结果(RESULT):每项任务在采取了行动之后的结果是什么,是好还是不好,好是因为什么,不好又是因为什么。
如果你把代码看得比人重要,那么你就无法真正建立起一个技术团队,即使候选人接受了录用通知书(Offer)也无法改变这个事实。
你必须明白,你在招聘过程中的表现在一定程度上体现了你的团队价值观,所以请无限高度重视招聘。
记住,招聘是一项长期且繁琐的工作,很多时候没法完全依靠HR,需要自己花费大量的时间和精力去寻找和沟通。即使如此,仍会有一些岗位长期空缺,找不到合适的人选。招聘一个技术人的时间、金钱、精力,以及培养的成本都是巨大的,如果留不住,就等于前功尽弃。
进入公司后就只看你的成绩
我们以Java程序员面试题为例:1)请使用两种设计模式编写代码(考察基础编程能力)。2)请描述面向对象的三个特性及使用场景(考察面向对象的基础知识)3)编写数据结构相关的程序,例如“实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作”(考察对于数据结构的了解)。4)编写算法设计题,例如“给定一个32位整数n,可为0,也可为负,返回该整数二进制表达中1的个数”(考察对于复杂算法的了解)。5)请描述JVM堆、栈、方法区的用处和区别(考察对于JVM的了解)。6)举例说明Java8与Java7的区别,写出对比代码(考察对于新技术的了解)。7)对您使用的GC作原理性描述(考察对于垃圾回收机制的了解)。8)举例说明某个JDK函数或者类的源代码并进行分析(考察对于技术原理的了解)。9)说说您过去的项目经历(开始了解他的工作经历,以便后续进行提问)。10)画出您最了解的项目的总体设计图,或者概要设计(了解他的架构设计能力)。11)说说过去工作中遇到的最复杂的技术难题,并说出您的解决方案(考察他的问题解决能力,也可以了解他所做的项目的复杂度)。
12)工作中您最讨厌领导的哪些行为?过去的经历中有没有发生什么不愉快的经历(了解他对领导的期望)。13)为什么离开上一家公司(可以深入聊聊,了解这个人的个性)?14)反问他有什么问题(别小看这一题,一般来说,如果他有自己的职业规划,他一定会问你很多关于你们公司、岗位的问题,或者如果他对这个岗位很感兴趣,他也会问。反之,如果他想都不想直接说没问题,那我觉得应该多和他聊聊为什么会来面试,仅仅是为了有一份工作吗)。
面试过程体现了一家公司的技术能力、思维和管理能力,绝不可以轻率应付,你代表着公司,而不仅仅是你个人,如果你不够资格,或者根本不想做好,那请你让开位子,请合格的人来坐。
面试时,我们可以通过提问的方式了解面试人为什么离开上一家公司,是不是发生了严重的冲突,或是存在隐忍的矛盾。如果你不善于观察一个人的心理状态,可以请HR协助一起面试,HR一般都受过专业训练,可以在短时间内判断某个人的心理状态和性格,这些都有利于你招聘。
公司派我们出去面试,代表的是公司的形象,这自然不用多说,另外需要注意的是,你面试的人是在整个公司使用的,不是只给自己使用的,所以需要对技术严格把关,加强责任心,只录取技术能力过关的、性格适合做技术工作的人,不要受自身情绪影响,导致录取不合适的人。
❑ 支配型(Dominance):在敌对的环境中保持主动的态度和反应;❑ 影响力(Influence):在友好的环境中保持主动的态度和反应;❑ 稳定性(Steadiness):在友好的环境中采取保守的态度和反应;❑ 遵从性(Compliance):在敌对的环境中采取保守的态度和反应;
只能当“独狼”的程序员不会在任何一家企业待太久。要么是你对他们总是自顾自地向前冲感到厌烦而辞退他们,要么是他们因长期受限制感到厌烦而主动辞职。
我的习惯做法是带着新员工逐一认识团队成员,自己带着他去食堂吃午饭,并指定新员工的导师(技术上的),然后和他聊聊最近一个月准备给他安排的工作等,等他和团队成员熟悉后,我会找机会组织全组人一起吃顿饭,一起欢迎新员工。
(1)没有对新员工进行明确区分
(2)忽略新员工直属主管的重要作用
(3)培训方式缺失
不要让你的下属陷入困境,不要让你的同事陷入困境,尤其是在任何情况下,都不要让你的上级陷入困境
“盖茨最喜欢和他的程序员一起将程序分析到比特、字节层面。在技术战斗中他可以非常轻易地守住自己的阵地,他之所以可以获得程序员的尊重,因为他可以轻易地战胜他们。”
成功地管理程序员最重要、最关键的因素,是在技术层面得到他们的尊重。
❑ 理解计算机程序设计的艺术 ❑ 拥有良好的过往履历 ❑ 做出过技术贡献 ❑ 追逐技术潮流 ❑ 成为一个技术或者职业组织的活跃成员 ❑ 展现出强大的个人价值
这些要素解释了为什么从公司外部招聘过来的技术团队管理者很难真正落地(短时间内开展有效的管理工作)。你所选择的这位空降管理者,你需要充分考虑他是否有良好、可以被证明的履历,这样才能让他获得团队的尊重。所以说,一般情况下技术团队是不会空降高管的。
2.强化现有的团队
杰出的程序员能够以一种优雅、简洁、易懂的设计来架构大型的复杂系统,这些优秀的系统往往能让所有其他程序员的工作都更加轻松
3.团队组成
杰出的程序员需要一群称职的程序员来配合,依赖他们完成日常的开发工作,实现设计好的系统和产品。
4.薪酬组成
5.进度管理
每天上午半天时间我会和每一个项目(产品开发、预研、调研等)的团队成员过一遍当前进展。
最高效的团队管理者往往都是坦率的,也往往对下属有足够的时间,能让员工找到他们并说出自己的想法,他们会认真倾听。
从长远看,一些不紧急但是很重要的事情,如果迫于压力被放下,到后面往往需要花费好几倍的代价才能弥补回来,技术管理者需要时刻保持警惕,慎重地做出决策,做正确的事情,要能够为公司的长远利益负责。
6.效率管理
那么如何提高效率? (1)提高效率,最重要的是先确保做正确的事,再把正确的事做对。因此,先明确目标和结果,以及结果对最终客户的价值大小,这是提升效率最重要的事。在这个基础上,我们会发现很多事情根本就不应该做,而不做就是最大的效率提升。减少一件事情,或者在事情中减少一个步骤,就是最大的效率提升。
(2)所谓效率其实就是性能。性能往往受限于系统的资源瓶颈。我们应该看清楚整个系统中的资源瓶颈是什么,是机器厂房、人力、资金预算,还是周转率,围绕它来组建流程,提升效率。
(3)高效与工具化、自动化程度强相关,因为自动化具有规范、一致、高速、闭环反馈等特性,而且不会因为疲劳而下降。因此高效率的组织,一定会大力发展这些能力。 (4)高效的组织,每个人都会主动优化流程,并且持续改进。
7.引导工作
引导的最终目的是为了让事情完成,而不是把关注点放在如何完成上。对于一个团队管理者来说,要想最大化地利用自己的时间和技能,就要引导程序员自己做出正确的决定,而不应该自己就把决定做了。这样做可以帮助下属员工培养技术、积累经验、建立自信,还能获得具体执行决定的员工的认同。
如果你发现自己经常需要讨论非常具体的命令以及如何执行,说明你没能很好地利用你的管理技能,或者没能赋予下属员工足够的权利。
记住,优秀的主管要有足够的自制力,不在下属工作时瞎指挥。
8.保护成员
我们要学会保护团队成员,让他们免受组织中的各种问题、争议和“机会”的干扰。
你应该保护你的员工免受开发之外的同事或者部门的攻击。
公司内部非重要部门组织的会议,尽量不要放在周五的晚上和休息日进行。利用这种休息时间,看起来很有效率,其实是在过度使用研发资源,过度消费员工对公司的满意度。周五晚上和休息日可以打扰研发人员的事情是: (1)现场问题,必须立即处理(不处理会损害公司未来利益); (2)重要客户提出需求,要求立即做出回复(不处理会损害公司当前利益); (3)特别重大的突发事件(对你和公司都很重要)。
信任但要核实
还要定期检查以下三个问题:“是否清楚整体的目标?是否清楚你的任务对实现整体目标有怎样的贡献?对于你所负责的部分,有哪些东西妨碍你达成目标?”
承担并顺利地完成与员工的主动沟通,这是你的职责,千万不要轻视沟通能力,这一能力对你的晋升起决定性作用。
两个人只有面对面坐下,看着对方交谈,沟通才不会有障碍。
团队越来越大时,信息之间的传递会变得越来越困难,技术管理者要想搞清楚项目执行的进度、团队成员存在哪些诉求和不满,想要打造一个有战斗力的团队,沟通无疑是最重要的。
团队Leader每两周组织一次与小组成员的一对一沟通,并在每个月底的时候召开一次全员例会,内容可以是欢迎新入职的同学、总结本月重要项目的进展以及存在的问题、介绍下个月要做的重点工作等,让大家对工作有一个整体的认识,并清楚知道自己在全局中所发挥的作用。
如果一名团队成员在你不太方便的时间来找你聊天,一定要先把手上的工作放下,专心跟他交流,他可能想鼓起勇气告诉你一件大事。
记住,没有记录的会议,相当于没有开过。每一个重要会议,都需要有完整的会议记录,包括参加人员、讨论议题(逐一写下来)、讨论过程大体描述、每一个议题的最终结论(包含流程图)、遗留问题、下一次会议时间及议题等。
抓大放小,注重结果。
程序员在工作中经常犯的错误是只见树木,不见森林。举个例子,程序员在得到用户需求后立即开始编程,解决用户的实际困难,但由于事先没有进行很好的策划与沟通,客户的需求总是在不断调整,程序员也总是在修改程序以满足客户的需求变化。这样一来,该项目的周期自然就一拖再拖,似乎没有终点。
管理者需要为成果而工作,以结果为导向。一位卓越的管理者不应该在工作一开始就身先士卒地从事具体的工作,更不应该把精力放在研究技术实现的细节上,而是首先问问自己:“客户期望我做出什么样的成果?”然后再对整个项目进行规划。
19.激励员工
我收到过一位网友的提问:“在没有奖金、没有加薪区别的情况下如何激励员工?”针对这个问题,想问他们家老板,连基本的激励都不存在,还怎么让员工做出成绩。
你老板的级别越高,你的报告就越要精简,越要注重大局,细节更少、局面更大、文字更少、项目符号更多。
所以双方应当一致迭代优化沟通,调整需要沟通的度量。有的事情需要更多的信息沟通,而有的则需要更少。
你还要避免只把问题带给领导的情况,最好是拿着几套潜在的解决方案和问题一起交给他。即使你没有特别好的解决方案,或者没有找到最好的解决方案,也会让领导觉得你已经做好了自己的功课,过来找他是为了寻求他的建议和忠告,而不是直接把问题抛给他。
对于所有的管理类问题,我觉得首先要自我检查,确保不是自身的问题,然后是沟通,保持高效、简单的沟通,这样可以帮助你至少说出自己的困惑,最后是放松自我,不要被不值得的事情或人所烦恼,过好自己的每一天,全力做好自己的工作,不断提升自我价值,抽出时间陪伴家人,这才是你应该做的。
如果对方是产品经理,尝试以产品的语言去解释。如果对方是计算机科班出身,那么简洁地使用计算机术语,直接说理论的名字或者算法的名字就行(如二次握手、NP等)。如果对方是其他专业转行的程序员,不妨试试直接拿着代码来讲。如果对方完全不是一个行业的,就尝试针对他了解的一些问题和知识来举例解释。
一般来说,你能够覆盖完整的团队成员,最好不要超过10人,多于10人以上,可以采用分小组形式间接管理。
智慧是您一生从聆听而非说话中所得的奖赏。 ——亚里士多德
建议你把自己放在金字塔的底部,而你的员工在顶端。他们和他们做的工作才是真正重要的。
举个例子,遇到业务方提出的需求完成时间点过于苛刻的情况(其实这是一个压力传导问题,业务方收到了客户的压力,本来可以通过向客户解释来减少研发的压力和风险,但是选择直接施压研发)。这时候,你的这位不懂技术的团队老大可能会说,没关系,我们一开始并不需要一个完美的系统,你先上了再说,我们后面有时间再重构和完善(当然有的技术人员也会用“架构和设计是逐步演化出来的”这句话来证明“故障驱动”开发是值得的),这样的想法本质上是错误的。
一些人喜欢将缺少需求分析、技术设计环节解释为“这是敏捷开发,和你们的瀑布式不一样”,这是对敏捷开发的误解,敏捷开发是很好的一套开发流程。敏捷开发的实质是为了解决需求快速变化的情况,需要快速响应需求提出方,快速搭建产品原型用于验证实际效果,而不是说有了敏捷就可以忘记软件工程理论,不管三七二十一,先随便写一堆代码再说,这是不合理的。任何软件工程模型,都不会允许在需求完全不明确、描述不清楚的情况下,开始进行技术方案设计,也不会鼓励在方案设计缺失的情况下开始编码,因为这个时候没有人知道究竟如何编码。 团队领导可以不是对口的专业出身,但是他必须对技术有热情,必须有开发经历,需要对技术有敬畏之心。总结为两点: ❑ 基础知识和理论知识非常重要,多多使用已有的且成熟的方案是关键。 ❑ 对技术要有一颗严谨和敬畏的心,想清楚了再干,坚持高标准,很多事情都急不来。
很多时候,员工其实并不在意工资低一些,但是如果他们发现同级别的人工资比他们多很多,这时候就会出现强烈的内心冲突,一般这种情况你需要立即处理,安抚他们,并解释为什么会出现这种情况,并承诺后续如何平衡。
在成长的过程中,捅娄子的事情不可避免,但只要勇于面对、积极改进,一般不要在这些事情上过于苛刻。
总的来看,对于薪资,我们应该注意以下几点: ❑ 按照能力和他的付出进行衡量,不要把个人情感混淆其中。 ❑ 制定标准化的考核规则,输出能够让人信服的流程和细则。 ❑ 薪资的组成结构最好能够多元化,这样可以让员工在每一项奖金中感受自己的付出和回报。 ❑ 薪资真的是第一要务,一定要把握标准,做到公平、公正,不然你的团队会垮的。
如果程序员觉得没有前途,不思进取,而资质较好的程序员很快又被提拔为管理者,那我们的软件开发将很难有技术和人才的积累。
作为一名团队管理者,有一点是需要做到:“不要作恶!”
每个会议都必须有一个决策者。如果没有决策者或者会议中无法产生决策,这个会就不应该开。
白天是用来开会的,晚上加班才有时间编程序。
一个程序员应该能够掌握多个语言,也能够负责多个模块甚至不同的职责。如果一个程序员觉得多学习一门语言,多掌握一个模块是件很困难的事,那么这个程序员本质上是不合格的。
真正应该关注的是工作能力是否自由,如果你能力很强,又很善于掌握新的技能,那你完全可以自己掌控自己的时间,可以自己创业,或者去那些愿意给你时间自由的公司,一切事在人为,关键还是自身。
最有效的领导方法,包括两个能力:一是愿景(Vision),二是沟通能力。
打造国内技术领先的前端团队。
《Thinking in C#》的作者Larry O’Brien和Bruce Eckel有这么一段评论:“计算机程序设计非常有趣。与音乐一样,它也是先天才华与刻苦练习相结合的产物。与绘画一样,它也可以有多种发展方向,商业、艺术以及纯娱乐。
所以,一个不能使用调试工具的程序会令程序员感到无比沮丧,只能通过跟踪信息来跟踪程序运行的过程。
把一个大问题分解为几个小问题,或者把一个复杂的过程分解为几个子过程,这样有助于问题的解决。这也是程序员常用的手段,如算法策略中的分而治之(Divide-and-Conquer)和合并排序就是这方面的例子。
如果程序员的学习、工作动力主要来源于项目管理时间表、管理层的压力,或者金钱,那么他不会成为一名杰出的程序员。对大多数杰出的程序员来说,动力实际上来源于更高的追求,例如改变世界,做出人们喜欢使用的程序或产品。杰出的程序员希望并且需要为具有世界影响的项目而工作,他们希望能够感受到自己的工作是有意义的,哪怕只在某个很小的方面有意义也行。杰出的程序员偏爱能够满足他们更高理想或要求的公司和项目,他们非常在意自己所做的事情,常常为了想要的结果而超负荷工作,而不会在某种压力下自愿做低技术含量的重复劳动。
真正到小米来的人,都是真正干活的人,他想做成一件事情,所以非常有热情。来到小米工作的人聪明、技术一流、有战斗力,这样的员工做出来的产品注定是一流的。
知识型员工的一个鲜明特点就是,对专业的忠诚大于对所服务的企业的忠诚,选择企业的目的是致力于寻求能够实现自身专业成就最大化的成长平台。
因为要考核业绩,几乎所有人都提出相对容易实现的低目标。 ❑ 因实行绩效主义,索尼公司内追求眼前利益的风气蔓延。这样一来,短期内难见效益的工作,比如产品质量检验以及“老化处理”工序都受到轻视。 ❑ 上司不把部下当有感情的人看待,而是一切都看指标。 ❑ 为衡量业绩,首先必须把各种工作要素量化。但是工作是无法简单量化的。公司为统计业绩,花费了大量的精力和时间,而在真正的工作上却敷衍了事,出现了本末倒置的倾向。
不要小看了这两个词的力量,正是这两个词决定了OKR和KPI的本质差异:OKR关注的是目标,KPI关注的是指标。当我们关注“目标”的时候,我们会思考接下来我要做的事情是什么;而我们关注“指标”的时候,我们会思考自己的工作如何评价。
以程序员为例,如果我们关注目标,我们会想接下来我应该做什么事情,是要解决产品的卡顿问题,还是引入大数据来做精准推荐;如果关注指标,因为我们的工作是编程,那我们就会想哪些指标可以衡量编程工作呢?我们想到的是代码行数、Bug数、单元测试覆盖率等。
彼得·德鲁克在《管理的实践》中说:“并不是有了工作才有目标,而是相反,有了目标才能确定每个人的工作。所以企业的使命和任务,必须转化为目标。”
OKR让我们做正确的事情,KPI让我们正确地做事情!
第3章 产品开发过程管理
无论多难,都要记住一点,只要别人不赶你走,你就厚着脸皮待下去,这样你才有可能熬到项目成功。
一个合格的开发经理必须同时做到“按预期交付成果”“让客户满意”“让员工满意”。
关于项目经理职位,想要走纯项目经理路线的同仁注意了,这是一条无悔路,后面会遇到的困难无数,如果半路发现实际情况和最初的想象有很多差距,觉得自己不适合做项目经理,那问题可就大了。因为,这不仅对外部部门和团队会造成非常大的不利影响,对自己也非常不利,毕竟技术的发展实在是太快了,再想退回到技术路线的难度很大。
开发经理的口号应该是“跟我冲”,而不是“给我上”。
积极主动的人最大的特点是不会经常抱怨,因为抱怨本身是没有用的。开发经理是项目组的“主心骨”,如果这个人很容易慌乱,那这个项目也会混乱。开发经理必须时刻保持好的心态,如果团队成员始终看到一个信心满满、镇定自若的开发经理,大家也会充满信心。如果团队总是看到一个整天愁眉苦脸、满腹牢骚的开发经理,大家可能担心他随时崩溃,自然自己也不会积极主动了。
瀑布式开发模型是一种严格按照需求—设计—实施—交付四个阶段进行软件开发的模型,并且在各个阶段结束时要经过严格的评审,只有当能够确认一个阶段的开发成果是正确时才能够进行下一阶段的开发。
这就是所谓的“敏捷”,核心就在于快速迭代并迅速反馈。
敏捷联盟在成立之初总结了四条基本的价值原则: ❑ 人员交流重于过程与工具(Individuals and Interactions over Process and Tools); ❑ 软件产品重于长篇大论(Working Software over Comprehensive Documentation); ❑ 客户协作重于合同谈判(Customer Collaboration Over Contract Negotiation); ❑ 随机应变重于循规蹈矩(Responding to Change over Following a Plan)。
极限编程、Scrum、特征驱动开发、测试驱动开发
需求的好坏,直接决定了开发、测试团队的工作是否存在价值。
里程碑包括4个要素:时间点、标志性事件、交付物、关闭条件。到达里程碑后要对项目进行评估,确定是按计划继续执行,还是进行必要的变更和调整。
❑ 介绍议程和来宾; ❑ 介绍项目目标、阶段计划、管理方法; ❑ 发布项目的组织结构图; ❑ 确认关键角色及其职责,并作出承诺; ❑ 参会人员针对介绍内容进行提问交流; ❑ 高层领导做项目动员发言,激励和鼓舞士气; ❑ 各个相关部门领导表态支持项目工作。
产品需求是根据用户需求转化而来的技术实现需求,需要针对用户提出的产品目标进行细分,总结出具体的功能点,再针对每一个功能点细分为各种不同的操作流程,对每一个操作流程进行技术化定义
。用户需求和产品需求容易产生差异,这是因为虽然大家都在谈需求,但是出发点可能不同,造成了双方关注点和思维方式不同。用户需求关注的是系统如何支持业务流程,背后的需求是“实现业务目标”。技术人员关注的是合理技术方案,背后的需求是“工作量”“实现难度”和“系统性能”。
整个方案的水平完全取决于讲解者一个人的水平,
召开产品或者技术方案会议的时候,大家最容易犯的错误就是,自己先绘制了原型图,甚至产品架构图,直接来讲解自己的方案。这是一个完全错误的会议方式,基本上浪费了所有人的时间。
建议需求评审会议可以分为三个步骤:会前提供材料,会中讲解、讨论,会后解决疑问、缺陷。
1)开任何会议,一定不要上来就讲解方案,应该先讲解场景。每个场景先讨论背后的需求并定义清楚,这也是软件本身的意义——模拟业务;2)大家一起讨论,研究这个场景背后的需求是不是最佳场景,能不能删除这个场景,或者是否有其他场景可以代替这个场景同时还能满足背后的需求;3)如果是需求的最佳场景,再开始讨论这个场景下的产品解决方案;4)这个时候你打开事先设计好的产品原型图、产品流程图、状态图、用例图,你会发现有很多需要修改,修改之后就是大家一起生成的方案。
我们需要弄清楚产品经理或项目需求提出者为什么要做这个项目,这是最本质的业务需求分析。需求分析确定的产品需求,都是从业务需求推导出来的,都必须为业务需求服务。
产品需求规格说明书一般包括以下几部分:1)简介:主要由产品功能和定位简介、常用产品和技术术语、本文参考资料等三部分组成。2)产品描述:包括产品介绍、产品范围,以及产品遵循的标准等。3)技术约束和局限:说明实现过程中需要满足的条件和所受到的技术方面的限制,并且说明原因。4)需求详细描述:按照功能进行划分,列举每一个功能需求,说清楚每一个功能的需求描述、优先级、参与者、实现前置条件、实现后的结果、功能执行过程中的正常过程(这一点是需求描述的重点,需要说清楚当没有任何错误发生时,参与者与产品的交互过程。这一过程展示了本功能的核心价值,每一个用例必须要有正常过程)、可选过程(另外一种正常过程)、异常过程(该过程一般会结束整个用例的正常执行)、特殊需求(一些非功能需求描述)、附加说明(与其他需求的相互关系说明)。5)接口需求:一般包括用户接口(提供用户使用产品时的接口需求)、硬件接口(指出每一个硬件接口的逻辑特点)、软件接口(其他软件调用接口)、通信接口(指定各个通信接口)等。
6)质量需求:一般包括性能需求(产品支持的用户数量、运行速度、对资源的利用率,以及正常情况下和峰值情况下的处理能力等)、可靠性需求(例如平均可用时间、平均故障时间及修复时间、准确性和精确度、错误或缺陷率)、可用性需求(要从用户使用的合理性和方便性等角度进行描述)、可维护性需求(例如行业标准、编码标准、开放性设计架构等所有有利于可维护性或可扩展性的需求)、安全性需求(保护产品的要素,防止各种非法的访问和使用)、可移植性需求(产品从一种环境移植到另一种环境所要求的用户程序、接口兼容方面的约束)、可测试性需求。7)用户文档需求:包括用户指南、联机帮助手册、安装指南、配置文件等。
在需求评审阶段,邀请产品、开发、测试相关人员进行需求评审,产品需求评审主要针对以下几个方面进行:❑ WHY:为什么做这个需求?❑ WHAT:需求的价值是什么?❑ WHEN:需求期望什么时候上线?截止日期?❑ HOW:需求是否完整?正常场景是什么?异常场景是什么?技术上分别怎么应对?
总体设计是整个系统的框架型设计,意义极其重大,一般情况下不能省略(只有维护项目可以省略总体设计,因为基准项目已经设计完毕),所有的产品开发项目均需要首先进行总体设计,它是设计首要步骤,决不允许本末倒置,不能出现先编码后设计的情况,这是软件开发的第二大痛点(第一大是需求不明确、任意变更需求)。
优化时遵守一句格言:“先使它能工作,然后再使它快起来。”
(1)优先考虑核心模块的压力测试 在对整个项目做设计、规划的时候,首先要对系统负载最高、开销最大,或者可能请求量最高的部分编写最基本的数据结构和操作逻辑,然后进行压力测试。
做好这一点,需要懂一些业务,你要知道业务压力在哪里,业务请求的重心在哪里,很多时候,产品经理不主动告诉你,你也要问清楚。
你的技术能力绝对不能被框架约束。
在使用新技术前,建议全面了解该技术的特征、适用范围,以及不适用的范围。
3.针对代码编写的十条建议
为循环设置次数界限,避免使用递归,这些做法有助于预防代码失控。然而该原则无法适用于本就不应终止的迭代(例如进程调度器)。此时将沿用该原则的逆向原则:必须能够静态地证明迭代不能终止。
试图分配超过可用物理内存数的内存。 2)忘记释放内存。 3)继续使用已被释放的内存。 4)对已分配内存进行越界使用:应强制所有模块位于固定大小、预先分配的存储区域中,借此可避免此类问题,并简化内存使用情况的验证工作。
原因:过长的函数通常意味着结构并非最优。每个函数都应是可理解且可验证的单一逻辑单位。如果在计算机显示器上需要多屏界面才能完整显示,这样的逻辑单位通常会极难理解。
断言的另一个重要之处在于,它是防御性编程(Defensive Coding)策略的重要组成部分。我们可以使用断言验证函数执行前后的状况,函数的执行参数和返回值,以及循环不变式(Loop-invariant)。在完成性能关键代码的测试工作后,可将断言选择性地禁用。
1.代码审核重要性 代码审核及其重要,一般来说每周都要做一次代码审核。代码审核有利于跟踪项目进展情况,我们能真实地看到其他人的工作进展如何,并且能更早发现他们是否误入歧途。有时候,手下人会说“完成得差不多了!”你去看代码时发现什么都没有,诸如此类,总之离完成还很遥远。在管理中,这种情况是最让人讨厌的,所以我认为代码审查是避免这种麻烦的最佳途径。
单元测试是一种白盒测试,就是必须要对单元的代码细节很清楚才能做的测试。
有一个方法可以判断是否为可测试的代码,就是看这个方法能否用一个main函数直接运行,如果可以的话就是可单元测试的代码。可测试的代码还有另一个特征,就是该方法单元的参数,开发人员可以自由模拟,不需要依赖外部环境。
如果代码里有逻辑,但是不可单元测试的话,就需要改造代码。改造的方法,就是要确保逻辑代码和外部环境相关代码隔离,这个逻辑代码就是可单元测试的。而隔离的办法就是把代码的执行顺序,也就是单元的执行生命周期,做架构的拆分。访问代码的核心就在于传递上下文的数据,因此先把逻辑需要的数据从上下文环境中取出来,给逻辑代码单独另建一个单元,再把从环境中取出来的参数作为入参传入新建的逻辑代码单元。这样新建的逻辑代码单元就只依赖入参而不再依赖环境,从而使开发人员可以自由地模拟输入参数做单元测试了。
5.单元测试优点 刚开始编写单元测试代码确实存在一定的代码量,会觉得有点占用时间。但是随着代码的深入,测试工作量会越来越小,因为单元测试做到位了,代码可以直接运行。反观手工测试,刚开始确实很快(需要测试的内容少),随着代码增多,手工测试工作量加大,反而花得时间更多,因为以前测试过的内容还需要重新再测,无法把自己的重复工作自动化。 一旦养成单元测试的习惯你就离不开单元测试了,因为一旦上瘾,会觉得没写单元测试代码就很不安。大部分时候,单元测试覆盖了100%,只要业务没有太大的变化,单元测试就不需要维护,即一次投入会持续受益。
2021/3/24 发表想法 一般来说,纯粹修bug也太难了,普遍都有其他事情干扰。
开发人员专注于修复Bug
总结项目经验教训的目的在于总结问题、分析原因,避免以后犯同样的错误,而不是追究谁的责任。
在质量管理的理论中,缺陷越晚发现,修复的代价就要乘上十倍。
项目经理需要在产品开发过程中召开一个或者多个复盘会议,会议要对项目启动会的每一个环节进行回溯。例如项目启动会是否准备充分,启动会现场是否有提问没有回答上来,为什么没有回答准确;产品需求是否按期完成、评审是否通过、为什么存在产品经理不满意产品需求的情况;总体设计是否提前与产品需求完成;总体设计、概要设计评审是否存在高优先级缺陷,为什么会有这样的缺陷存在,是不是设计阶段没有考虑周全;单元测试是否完成,为什么单元测试效果不好;系统测试阶段发现了哪些高优先级缺陷,冒烟测试是否通过,为什么没有通过。
可以复盘的内容很多,一位严格、高水平的技术经理,这一环节应该是他花费大量时间的环节。复盘的参与人员不用很多,只需要该产品的开发人员参与就可以了。再重申一句,复盘会不要太严肃,它不是“批斗会”,而是为了总结经验,不断优化,不再犯同样的错误。
业务问题的本质是业务所服务对象的利益问题。根据业务对象的利益,可以整理出业务的生命周期和生命周期的拆分,再根据业务的概念和组织方式,可以分析出业务的核心生命周期
“向进度落后的项目中增加人手,只会使进度更加落后”,这句话摘自《人月神话》。
伊格尔森定律(Eagleson’s Law):“自己写的代码如果有半年时间没有看过,就跟别人写的代码没什么区别了。”这句话的意思是,代码看起来会很混乱、难以理解,并且同样无法通过进度估计来预测项目成功完成的时间。
为了有效控制进度,开发经理需要请各个小组每天召开“晨会”以检查昨天工作进展,并且布置当天工作;另外,每周五下午召开周例会,项目组全体成员都要参加。
2.周例会 周例会检查和调整项目计划,关注的问题是:任务完成了吗?没完成的原因是什么?怎么调整?先确认了状态,再讨论该如何调整工作或计划,并一定要落实到具体的行动方案上。  只有提前建立工作结果的验收标准,才能确定如何才算是完成任务了。 项目计划要想落地,需要细化分解到每个人的工作任务中去。个人工作计划可以通过白板的方式管理,它可以实时反映进展情况。 计划进行调整和更新是常态,因为“计划本身没有用,不断地进行计划才有用”。底层计划的管理使用简单的白板就可以发挥巨大的作用,可见软件开发中“人”才是最重要的,没有“人”的主观能动性,再高级的管理工具也难以发挥作用。
根据时间管理的经验,安排工作的原则顺序为:重要/紧急工作>重要/不紧急>不重要/紧急>不重要/不紧急。
记住,在资源和进度都有严格限制的情况下,需要考虑集中优势资源优先完成高优先级的需求。
3.3.7 项目管理重要性
项目管理是一种软实力,只有逻辑能力强、对于业务和技术都非常了解的人才能既做好开发经理,也做好项目经理,其实也只有两者都管理得当,我们的开发项目才能够真正发布成功。
项目进度把控:技术人员很容易犯的错误是技术优先,对项目的进展不太关注,而项目管理的目标就是要让这一点不出现问题,也只有做好项目管理才能真正解决进度把控问题,你不能单纯地认为只需要给开发人员添加KPI就行了,如果真的可以,为什么会有OKR的出现?为什么日本的软件企业越来越不行了,要知道,他们可是KPI的发明人和强有力的执行者。
人员工作安排:缺少强有力项目管理能力的技术领导,很容易让团队的部分成员陷入迷茫。提出的命题很大,但是落实到每位技术人员身上,一部分人会迷茫,不知道每天应该干点什么,所以最好的方式是对工作进行拆分,每天的工作要能说清楚它的具体目标、要求标准等,这样才能让大家有存在感和参与感。
他们的理念是不问用户想要什么,问自己内心,问自己内心想要什么就好了。
质量是一种管理,是一种控制,是一种预防。只有成熟的组织,成熟的团队,才能做出高水平的产品来。
测试工作最容易被压缩,一旦进度紧张,开发经理就会本能地选择压缩测试时间。要知道,测试是保障交付质量最常用也是最有效的手段,V模型中的每种测试都有自己的目的和针对性,不能相互替代。这好比在系统前拦上了一道道不同的网,只有每道网尽量多拦截缺陷,才能保证最终交付的质量,如果每道都放行,最后问题就会集中爆发。
[插图]
测试驱动开发(Test-Driven Development, TDD)是一种不同于传统软件开发流程的新型开发方法。它要求在编写某个功能的代码之前先编写测试代码,然后只编写测试能通过的功能代码,从而推动整个开发的进行。这有助于编写简洁可用和高质量的代码,并加速开发过程。 TDD的基本思路就是通过测试来推动整个开发的进行。而测试驱动开发技术并不只是单纯的测试工作。 需求向来就是软件开发过程中感觉最不好明确描述且易变的东西。这里说的需求不只是指用户的需求,还包括对代码的使用需求。很多开发人员最害怕的就是后期还要修改某个类或者修改、扩展函数的接口,为什么会发生这样的事情?就是因为这部分代码的使用需求没有很好的描述。测试驱动开发就是通过编写测试用例,先考虑代码的使用需求(包括功能、过程、接口等),而且这个描述是无二义的,可执行验证的。 通过编写这部分代码的测试用例,对其功能的分解、使用过程、接口都进行了设计。而且这种从使用角度对代码的设计通常更符合后期开发的需求。可测试的要求,对代码内聚性的提高和复用都非常有益,因此测试驱动开发也属于一种代码设计的过程。 开发人员通常对编写文档非常厌烦,但要使用、理解别人的代码时通常又希望能有文档进行指导。而测试驱动开发过程中产生的测试用例代码就是对代码的最好解释。
TDD的基本思想就是在开发功能代码之前,先编写测试代码
每先写一个测试都是在试图用自己对问题和需求的理解来定义实现代码的框架。从测试的不同角度,范围、边界、大小、功能等来定义实现代码将来会是个什么样子。一个测试接着一个测试,利用TDD的过程,恰好不多不少,正好驱动出解决这个需求和问题的实现代码来。
任何程序员都能写出机器可以阅读的代码,但只有好的程序员才能写出人可以阅读的代码。这句话道出了要写出容易阅读的代码的难度。
真正的技术和业务驱动的差距在于业务看的是今天,或者是短暂的明天,而技术放眼的是未来。但这并不是说学习算法和基础没有用,这是为业务提供理论基础,只有将技术应用到业务中,才能充分发挥它的作用。大家要明白,技术只有支撑了业务,你才有未来,不能解决当前业务问题的技术人员,不要谈理想,因为只有能够解决问题的人,才配谈技术理想。当业务出现问题的时候,技术人员应该立即站出来,去了解、理解业务,用自己的技术手段结合业务来解决问题,而不是觉得学习技术没有用,这种想法本质上是错误的。
3.3.15 倾听的重要性当你听别人说话时,你真的听懂了他说话的意思了吗?你是不是也习惯性地用自己的想法打断对方的话?不听人把话说完就断章取义下了定论,误会了对方的美好意愿,扼杀对方的创造力和主动性。我们以用户需求和产品需求差异为例。由于立场、关注点不同,用户需求提出方和产品需求制定方很容易发生分歧。要想确保用户方满意,必须从用户的角度看问题,了解清楚用户表面需求背后的“需求”,换位到用户的立场,如果你自己作为用户都不满意做出来的产品,那你的产品绝对是有问题的,晚改不如一开始就充分理解清楚,避免出现分歧,因为最终是由需求提出方(产品经理)来判断项目成败。
3.3.16 事必躬亲的错误事必躬亲是对员工智慧的扼杀,长此以往,员工容易形成惰性,责任心大大降低、技术能力止步不前。情况严重者,会导致员工产生腻烦心理,即便工作出现错误也不愿意向管理者提出。多让员工参与到需求讨论、软件设计中,这是对他们的肯定,也是满足员工自我价值实现的精神需要。赋予员工更多的责任和权力,他们会取得让你意想不到的成绩。
第4章 技术调研/预研
❑ 为什么需要进行技术调研。❑ 什么是技术调研,具体的思路、过程是什么样子的。❑ 什么是技术预研,具体的思路、过程是什么样子的。❑ 其他相关讨论。
技术调研是针对粗粒度需求实现方案进行的研究,很有可能对所需技术根本不清楚,需要通过调研项目来完成技术了解、技术选型、技术可行性分析、技术方案设计等工作。技术预研是针对细粒度需求的实现方案进行的预先尝试,主要针对的是通过技术调研所选择的技术,同时结合我们产品化时的实际需求,对实现时存在的不确定性因素、细节等进行预先研究、尝试,从而减小产品化过程中的技术实现风险。
技术调研报告首先阐述从需求整理到明确方向再到搜索技术调研方案及初步筛选的过程及结果,接着介绍具体的测试方案确定、测试环境搭建、测试用例编写及运行的过程,最后针对调研项目中得到的一些实际业务场景下的运行数据进行对比、分析,通过解释数据产生的原因来明确下一步计划。
调研的过程是怎么样的、为什么选择这些技术作为调研方向?1)这些技术分别是什么?2)技术调研方案、用例分别是什么?3)各个技术或框架之间的区别是什么?4)各个技术在通用场景下的优缺点是什么?5)各个技术在用户提出的特定业务场景下的优缺点是什么?6)根据得出的测试数据,为什么会有这样的结果?
介绍跟需求相关的前置知识; ❑ 目前有哪些方案,具体分析各个方案的优缺点及适合的场景; ❑ 技术调研的结果是怎样的,不可行的话是因为什么,可行的话说说最终决定使用何种方案(自己无法决定的话可以开个分享讨论会),并说说该方案跟其他方案比有何优势; ❑ 假如是新库的引进,需要简要介绍该库的使用方法及内部原理; ❑ 调研过程中碰到了哪些问题,如何解决
需求整理→明确技术方向→搜索技术调研方向→调研方向初步筛选→选择技术调研方向→确定调研测试方案及用例→调研执行→调研数据对比→调研结论
2.技术选型
(2)何时开始 原则上说,应当选择投资回报最大的时间点开始。大多数技术是用来解决特定问题的。你遇到了那个问题吗?那个问题重要不重要?会不会节省很多时间?新技术带来的好处能不能抵消学习成本和重做的成本?如果我们的开发速度从一开始就降低到正常水平1/2甚至1/4会如何?想想新技术还值得吗? 优秀的团队有更多自主权——一些团队确实比其他团队更快出成果,他们也更容易厌烦自己手头的工作。这些团队可以更多、更快地引入新技术,但这不是省略快速搭建原型或者黑客马拉松的理由。相反,如果这样的团队在交付上遇到了麻烦,一定要加倍小心。
(3)找到对的人 有良好技术背景的人——那些人了解不同的范式,理解编程的理论(算法和并发),受过良好工程文化熏陶,这样的人很少会去凑热闹。 有经验的人——年轻的开发人员更喜欢凑热闹。如果有多年的开发经验,见过许多技术,踩过许多坑,在技术决策时就更容易做出客观的判断。
4.3 技术预研
2. Apache Licence 2.0
作为一名技术团队的管理者,你必须了解当前技术发展趋势,并能够对趋势进行分析,进而明确自己团队未来1年、3年,甚至是5年、10年的发展目标。要拥有这一能力很难,但是你不得不做到。
对开源的贡献成为相当一部分技术人员的一种技术理想。
开源不仅意味着公司技术有了影响力,而且开源后技术需求的输入会变多,外部会给内部提供许多技术需求,从而通过从外部推进内部加快技术产出与技术创新。创新后再回归到开源,进而构成技术闭环。需求持续输入可让技术像产品一样迭代升级,提升功能单一的技术生命周期;需求多样化可以提高创新能力,从而让技术更有生命力。 在获得影响力之后,简历的收集渠道会扩宽,会有同行主动给你发简历;同时也会给现在团队成员带来平台的成就感,也能让外界技术人员对团队成员产生认同感,这对于技术人员来说非常重要。
第5章 系统架构
软件架构就是通过对软件生命周期的拆分,在符合业务架构的前提下,达到软件本身访问增长目的的方式
分工清晰后,会给创业公司带来一定的麻烦,因为招聘岗位太多,造成薪资负担很重,希望能够招到牛人,什么都能一人干完。所以现在又开始流行全栈工程师,这类人能够胜任从产品到技术到测试所有工作,其实这是自然架构的一种倒退,必然会遇到问题。
架构拆分的原则,首先来源于业务自身的组织架构,软件架构要保持和业务组织架构的匹配关系。
架构追求的实际上是业务不断长大:通过对业务生命周期的拆分,突出并精简业务核心生命周期,弱化非核心生命周期,达到不同生命周期可以在空间和时间上并行,便于不同的人同时开展工作,提升业务人员单位时间内的产出。
1.为什么需要架构师? 我们需要有人能够回答这些问题: ❑ 我们这个系统的边界是什么? ❑ 我们系统由哪几部分组成? ❑ 各模块之间怎么通信? ❑ 选择什么样的基础技术? ❑ 为什么要这样选择? ❑ 技术方案未来会遭遇哪些坑? ❑ 我们的备选方案有哪些? ❑ 从技术角度这个应用将来如何持续扩展功能? 这一系列的问题归咎为规划,因为做所有事情都需要规划,对于研发流程而言,规划阶段就是我们的总体设计阶段。一个复杂的软件系统更需要规划,如果没有规划可能连一行代码都很难写出来(当然会有人持反对意见,因为他们用一堆框架搭起一个系统,虽然没有设计环节,但是貌似还能正常运行。但是别高兴得太早,当你遇到业务急速扩充,系统出现各种异常情况时,你会被拖垮)。这个问题从一个程序员的角度去思考,其实也是一样的,你在写一个上万行的代码时难道是想到哪里就写到哪里吗?
架构师要解决的问题都是人的问题。更进一步,架构师要解决的问题基本都是别人的问题。别人的问题解决了,架构师自己的问题才能解决。任何找上架构师的问题,基本都不是真正的问题。为什么呢?因为如果是真正的问题,提问题的人肯定能够自己解决,不需要找架构师。因此,架构师都要有觉悟,理解并发现问题永远比解决问题更加重要,遇到问题首先进行分析,不要急于解决问题。
软件架构师必须是一个组织的领导人,有权利调整这个组织的架构,才能够更好地发挥架构师的作用,才能够把软件开发生命周期、软件运行生命周期和业务生命周期的拆分落实执行。
一名优秀的技术管理者,技术在前,管理在后,并不是说两者有太大的轻重差异,而是你需要花费70%的时间在技术上,只能花30%的时间在管理上,但是你需要用这30%的时间做完100%的管理工作
架构在软件发明前就已经存在很久了,我们应该多向大自然、艺术界、建筑界学习架构的概念,因为软件并不是虚无缥缈的事物,它和我们的现实生活是紧密相关的,它来源于生活,最终又通过软件服务回到生活。
团队达到一定规模之后,技术管理者(也可能有独立架构师存在)的大部公时间就需要花费在思考上面了,当然也可以继续编程,但是编程的目的是验证架构是否合理,所以不要受是否需要编程这一思维的束缚。如果设计得不好,那么团队就会走很多弯路,如果想要设计得很好,你必须自己或者带领团队做很多的测试、预研工作。作为架构师,你需要多多思考,很多时候因为很忙、事情很多,导致真正思考时间太少了。
架构的目的就是为了增长,而要达到增长,就必须让很多人合作为完成同一件事情,并且使他们做的事情合并起来达到1+1>2的效果,最少也要达到1+1=2的效果。
这就是架构师和技术人员的分工配合,架构师负责拆分生命周期,技术人员负责实现生命周期。
按照任务调度数量对源数据进行划分,比如3个任务调度服务,源数据按照行号对3取余的方式进行划分,如果运行了一段时间之后,任务调度服务出现了数量上的增减
一个技术团队必须有自己的技术定位,也可以说是有技术愿景,只有这样才能留住对技术很有热情的工程师。
业务需求是技术推动力。
“不应该一开始就承担大项目。应该先从小的、无关紧要的项目入手,并且不要去希望该项目能够做大。否则,你就会做出过度的设计,并且通常会把项目的重要性看得比它实际的要高。或者更糟的是,你会被预想的不切实际的项目规模吓得望而却步。因此,要从小规模的项目做起,把细节考虑周全,不要盲目憧憬过大的愿景或虚幻的设计。如果项目不能解决一些相当紧急的需求,那么它十有八九是被过度设计了”。这是林纳斯·本纳第克特·托瓦兹(Linus Benedict Torvalds)的观点。他是著名的电脑程序员、黑客,Linux内核的发明人及该计划的合作者。
5.2.3 学习能力
你每天7点起床,23点睡觉,中间所有空闲时间都拿来学习、思考、总结技术问题,你就可以提高了。
任何人想要提升自己的专业能力,有效、高效、有针对性地付出时间是最直接、最有效的办法。
概念的建立不是一蹴而就的,需要反复地推敲、对比、自我否定。问题的定义更是自我意识游走在理想与现实之间,尝试各种问题边界的可能,不断地进行权衡。人生贵在坚持批判性思维,而不是简单的批评与抱怨。所有这些行动都是很困难的,因为它们会产生巨大的认知摩擦。
没有永远最好的技术,也没有永远最差的技术,问题总是在不断发生变化的,对于这一点,架构师要有清醒的认识。
我要问的是计算机科学基础知识,可以聊算法、聊数据结构、聊设计模式、聊你参与过的系统架构设计、聊内存管理机制和垃圾回收机制、聊你对于技术的情怀。框架的选择,实质上是对技术可行性的选择,这又需要符合当前的业务形态,所以,没有哪一个技术或者框架是最好的,只有最适合你的产品需求的,才是最好的。
你要知道,任何技术都是为了解决某种问题而存在的,学会了很多技术,并不代表能够利用这些技术来解决问题,学会的技术多只是解决问题的手段多了一些而已。
技术人员如果要成为架构师,必须跳出技术的视角,换一个角度去看技术。要把时间花在研究生命周期规律和业务的增长上,花在选择合适的技术上,而不是漫无目的地追求新潮的或是自己喜欢的技术。
如果只顾着完成自己的工作,而业务的问题没有解决,那么很可能需要返工,从而导致软件工程师投入更多的时间。工作是否完成是由业务人员决定的,而不是软件工程师自己。
谈到树,就必须要提到分层。分层实际上是架构树状拆分的结果,所以当我们采用分层的时候,内心先要有树的概念。如果我们直接采用分层的方式设计,最后就会违背树的原则,导致很多复杂的问题发生,从而影响到系统的长大,例如跨层访问形成了图,这就违反了树的原则。
业务、架构和技术之间是共生的关系,而不是互斥的关系。 技术人员很多时候所关心的技术,和业务的主要目标往往不是直接对应的。由于业务和技术属于两个不同的树,也就是说有两个不同的根节点,因此只有沟通才能解决问题。 技术总是在人类对业务目标要求不断提高的情况下产生,其目的是为了获取更大的利益。所以,技术是为了解决业务问题而产生的,没有了业务,技术也就没有了存在的前提;有了更好的技术后,效率较差的技术,就会慢慢被淘汰,进而消失,一切都遵从人类的利益诉求。
不同技术之间有两种关系: 1)在解决同一个业务的前提下,更高效、更低成本的技术会淘汰低效、高成本的技术。这是由人类利益诉求所决定的。 2)通常刚开始解决核心业务问题的核心技术的效率是比较低的,只是把不可能变成了可能。慢慢就会有提高的需求出现,改进技术的要求就会变得很迫切。技术所解决的业务生命周期慢慢就会开始发生拆分。非核心生命周期分离出去后,要么使用现在的技术来实现,要么形成新的技术,服务于更广泛的业务。
业务是核心,技术是解决业务问题的工作,而架构是让业务长大的组织方法。
一个好的架构拆分会形成一棵树,慢慢会长大成一片森林。每棵树在这个森林里都能够获得所需要的养分,有自己的空间。每棵树的内在是平和的、舒展的,遵循自己的生命周期规律,顺其自然地长大,一派欣欣向荣的景象。这就是架构的魅力所在。
系统定位和边界要清晰,对应的业务定位和边界要清晰。
架构设计核心目标是支持业务,有时候不合理的存在是合理的。
业务还在试错期,系统需要尽快保证支持业务试错,如果一上来就谈论整体架构的合理性,很可能花费巨大成本实现了合理架构后,新业务已经取消或失败。优秀的架构师和CTO要懂得在合理架构设计和灵活多变的业务发展之间做出智慧的权衡取舍。
系统架构师是一个最终确认和评估系统需求、给出开发规范、搭建系统实现的核心框架、澄清技术细节、扫清主要难点的技术人员,主要着眼于系统的“技术实现”。
要想使用开源技术,就要理解开源技术都有哪些特定的使用场景,采用之前必须了解这些技术原本是用来解决谁的问题的。如果不先搞清楚就使用这些新技术,很有可能会导致更高的研发成本。小流量的公司采用针对大流量的新技术,仅仅维护和监控就足够让人头疼。如果环境配置跟不上,则技术是无法发挥作用的。新技术最重要的配置就是人的配置,以及人的观念的配置。 作为开源技术的使用者,要掌握作者的理念,一般要先从理解作者面对的问题入手,也就是从业务入手,分析作者是如何拆分业务生命周期的。从这个角度来说,看代码和看书没有区别。