精华内容
下载资源
问答
  • 可以“建议”。建议,通常是在适当的时候指针对一个人或一件事的客观存在,提出自己合理的见解或意见,使其具备一定的改革和改良的条件,使其向着更加良好的、积极的方面去完善和发展,是有益处的。出处魏巍《东方...

    可以用“建议”。

    建议,通常是在适当的时候指针对一个人或一件事的客观存在,提出自己合理的见解或意见,使其具备一定的改革和改良的条件,使其向着更加良好的、积极的方面去完善和发展,是有益处的。出处魏巍《东方》第三部第十三章:“她的建议立刻得到热烈的响应。”

    拼音: jiàn yì

    ①对事情的处置或兴办提出具体的意见。

    《汉书·贾捐之传》:“诸县更叛,连年不定。上与有司议大发军, 捐之 建议,以为不当。” 唐封演《封氏闻见记·石经》:“天宝中,予在太学与博士诸生共论经籍失正,为欲建议立大 唐 石经,迁延未发。”谢觉哉《送军官家属还乡》:“我建议你们最好到三十岁才结婚。”

    ②指所提出的意见。

    魏巍《东方》第三部第十三章:“她的建议立刻得到热烈的响应。”

    ③建议,通常是指针对一个人或一件事的客观存在,提出自己的见解或意见,使其具备一定的改革和改良的条件,使其向着更加良好的、积极的方面去完善和发展。

    造句:

    1. 同学们围绕着课外活动问题提出了很多建议。

    2. 他力排众议,采纳了张扬的建议。

    3. 工厂采纳了爸爸的合理化建议。

    4. 用不着让他提什么建议,他总好王婆卖瓜,自卖自夸。

    5. 他们的建议不仅一钱不值,而且包藏祸心。

    展开全文
  • 公文精选致力于为广大公文写作者提供一个开放的交流平台。分享素材供大家学习参考,关注本号获取更多公文写作素材、优质范文、写作技巧、职场规则等!...01“领导,你在哪呢”给上级打电话,开口就问:“领...

    公文精选致力于为广大公文写作者提供一个开放的交流平台。分享素材供大家学习参考,关注本号获取更多公文写作素材、优质范文、写作技巧、职场规则等!如果您正在被写公文困扰,可以私信我哦,海量素材与君分享!

    也许你很困惑自己明明很努力为什么领导那里不冷不热?你兴致盎然的一句话为什么领导却神色黯然?

    可能是因为你不小心说错了话,而不自知,导致你的总体印象被降了分。

    01“领导,你在哪呢”

    给上级打电话,开口就问:“领导您在哪呢?或者,“领导您在干什么呢?”

    这是我们给朋友打电话经常用的开场白,可是在职场中给你的上级打电话这么说就不合适了。

    领导在哪里、在做什么需要给你汇报吗?所以合适的方式应该是,打通电话后,问“领导,您现在方便吗?”然后再开始说你想说的话。

    或者是先发个微信问一下领导,“我有个事需要电话给您汇报一下,您接电话方便吗?”

    02“领导我给你说一下”

    给上级报告工作或事情,开口就说:“领导我给你说一下”。

    说一下是告知一声的意思,作为下级对上级领导说说一下显然不太适宜。

    合适的方式应该是“领导,我给您报告一下、我给您汇报一下或者我给您请示一下。”

    03“我希望各位领导多给我批评指正”

    个人总结或者汇报结尾,说“我希望各位领导多给我批评指正。”

    这句话虽然表达的意思没有问题,但是希望一般应是上级对下级或者长者对幼者的期待,而下级对上级使用则不太合适。

    合适的说法应该是“我恳请各位领导多给我批评指正。”

    04“我代表我们领导…”

    在对外场合中,说:”我代表我们单位,或者我代表我们领导.....”。

    一般只有领导才能代表单位,如果你是一个部门的负责人,你也只能代表一个部门,上级能代表下级,下级代表上级就不太合适了吧?

    所以即使被安排代表单位出席活动,也应该说:“我受我们领导委托......”会更为适宜。

    05“这事不归我负责”

    领导或者同事问你一件事,你开口就说“这个事不归我负责”或者“这个我不清楚”。

    虽然你说的可能是实话,但是听了会让人不舒服,会让人觉得你爱推活不愿担责的感觉。如果问的事确实不是你负责或者不是你职责范围内。

    回答“您问的这个事好像是XX负责”或者“您提的这个事是XX处的职责”会让人感觉更舒服。

    因为一是肯定的回答总会比否定的回答让人感觉更好接受,二是也会让领导感觉到你对单位工作、职责的了解更全面、更用心。

    06“您听明白没”

    上级汇报完工作或者跟同事说一件事后,问“您听明白没”或“您听懂我的意思没”。

    如果想确认自己说的话对方是不是完全理解了,应该问“不知道我说清楚没”或者“不知道我说明白没”,把说明白的责任归结于自己,而不是把听明白的责任归结为对方,会让人更容易接受。

    总之,同样的一句话,敬字为先,谦逊低调,会给人一种无害有教养的感觉,有助于你收获良好的人际关系和领导的青睐。

    07 学会“好的”有多重要

    我花了将近10年时间,知道了在体制内会说这两个字最重要。

    我是学法律的,学法律的人有一种思维模式,叫做否定式思维。

    因为要锻炼在法庭上的对抗模式,我们曾经有专门的练习,就是对方不管说什么,我们的回答都是,不,然后再阐述自己的观点。

    当然,否定式思维模式并不是法律人专有属性,很多人都有。

    可是,我毕业后,没有从事专门的法律业务。而是进入体制,成为了一名跟公检法没有关系的公务员。

    我发现,这个思维模式,减缓了我的进步速度。因为在体制内,服从是很重要的一项要求。

    尤其是,你还不够强大时,不要过多的太着急或太坚定的表达自己的观点。

    我发现会说“好的”这两个字尤为重要。领导给你布置工作,先别急着阐述思路,或者提出困难,先回答“好的”,再慢慢阐述,领导会比较容易接受。

    同事跟你商量事,不要急着否定或拒绝,先说“好的”,再进一步沟通,协商起来会更顺畅。

    因为,“好的”这两个字,代表的不是你的立场,更多的是代表你的态度。只有在态度良好的基础上,才会有更好的沟通效果。

    以上仅为作者观点不知您是否赞同呢?

    展开全文
  • 一共有4级菜单,要实现全选和反选功能,当下级有一个被选中时,上级也要被选中;当下级全部未被选中时,上级也不能被选中。 网上搜了一圈也没有找到合适的,elementUI的tree组件虽然功能能实现,但是改样式又不方便...

    文章先发布于我的个人博客站点上,戳这里

    最近,由于公司后台管理系统重构,需要一个用到如图所示的一个功能:

    项目使用的Vue和elementUI

    一共有4级菜单,要实现全选和反选功能,当下级有一个被选中时,上级也要被选中;当下级全部未被选中时,上级也不能被选中。

    网上搜了一圈也没有找到合适的,elementUI的tree组件虽然功能能实现,但是改样式又不方便,于是,只好自己撸一个了。。。。不写不知道自己有多菜!这个东西居然耗时一天。。

    这个功能被抽离出来,做成了一个单独的组件。

    下面记录下主要的代码: 后台返回的菜单数据格式

    let menuData = [
        {
            "id": 1,
            "menName": "管理模式",
            "path": "manageMode",
            "businessCode": "manageMode",
            "parentId": 0,
            "isChecked": null,
            "menLevel": 1,
            "subMenuPermissionsVO": [
                {
                    "id": 105,
                    "menName": "首页",
                    "path": "/index",
                    "businessCode": "index",
                    "parentId": 1,
                    "isChecked": null,
                    "menLevel": 2,
                    "subMenuPermissionsVO": []
                },
                {
                    "id": 106,
                    "menName": "工作报表",
                    "path": "/report",
                    "businessCode": "report",
                    "parentId": 1,
                    "isChecked": null,
                    "menLevel": 2,
                    "subMenuPermissionsVO": [
                        {
                            "id": 107,
                            "menName": "数据总揽",
                            "path": "/reportOverView",
                            "businessCode": "reportOverView",
                            "parentId": 106,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": []
                        },
                        {
                            "id": 109,
                            "menName": "客服",
                            "path": "/reportService",
                            "businessCode": "客服",
                            "parentId": 106,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": [
                                {
                                    "id": 110,
                                    "menName": "工作报表",
                                    "path": "/report-service-workreport",
                                    "businessCode": "工作报表",
                                    "parentId": 109,
                                    "isChecked": null,
                                    "menLevel": 4,
                                    "subMenuPermissionsVO": []
                                },
                                {
                                    "id": 111,
                                    "menName": "工作质量报表",
                                    "path": "/report-service-qualityreport",
                                    "businessCode": "工作质量报表",
                                    "parentId": 109,
                                    "isChecked": null,
                                    "menLevel": 4,
                                    "subMenuPermissionsVO": []
                                }
                            ]
                        },
                        {
                            "id": 112,
                            "menName": "留言报表",
                            "path": "/reportLeaveWords",
                            "businessCode": "留言报表",
                            "parentId": 106,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": []
                        },
                        {
                            "id": 113,
                            "menName": "访问轨迹",
                            "path": "/reportWebsite",
                            "businessCode": "访问轨迹",
                            "parentId": 106,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": []
                        }
                    ]
                },
                {
                    "id": 114,
                    "menName": "历史会话",
                    "path": "/history",
                    "businessCode": "历史会话",
                    "parentId": 1,
                    "isChecked": null,
                    "menLevel": 2,
                    "subMenuPermissionsVO": []
                },
                {
                    "id": 115,
                    "menName": "客服管理",
                    "path": "/service",
                    "businessCode": "客服管理",
                    "parentId": 1,
                    "isChecked": null,
                    "menLevel": 2,
                    "subMenuPermissionsVO": [
                        {
                            "id": 116,
                            "menName": "所有客服",
                            "path": "/service-all",
                            "businessCode": "所有客服",
                            "parentId": 115,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": []
                        },
                        {
                            "id": 117,
                            "menName": "角色设置",
                            "path": "/service-role-setting",
                            "businessCode": "角色设置",
                            "parentId": 115,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": []
                        }
                    ]
                },
                {
                    "id": 118,
                    "menName": "企业账户",
                    "path": "/business",
                    "businessCode": "企业账户",
                    "parentId": 1,
                    "isChecked": null,
                    "menLevel": 2,
                    "subMenuPermissionsVO": [
                        {
                            "id": 119,
                            "menName": "团队信息",
                            "path": "/business-team",
                            "businessCode": "团队信息",
                            "parentId": 118,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": []
                        },
                        {
                            "id": 120,
                            "menName": "当前服务详情",
                            "path": "/business-service",
                            "businessCode": "当前服务详情",
                            "parentId": 118,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": []
                        },
                        {
                            "id": 121,
                            "menName": "团队联系人",
                            "path": "/business-contacts",
                            "businessCode": "团队联系人",
                            "parentId": 118,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": []
                        }
                    ]
                },
                {
                    "id": 122,
                    "menName": "设置",
                    "path": "/setting",
                    "businessCode": "设置",
                    "parentId": 1,
                    "isChecked": null,
                    "menLevel": 2,
                    "subMenuPermissionsVO": [
                        {
                            "id": 123,
                            "menName": "系统设置",
                            "path": "/setting-system",
                            "businessCode": "系统设置",
                            "parentId": 122,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": [
                                {
                                    "id": 124,
                                    "menName": "个人信息",
                                    "path": "/setting-userinfo",
                                    "businessCode": "个人信息",
                                    "parentId": 123,
                                    "isChecked": null,
                                    "menLevel": 4,
                                    "subMenuPermissionsVO": []
                                },
                                {
                                    "id": 125,
                                    "menName": "修改密码",
                                    "path": "/setting-change-pwd",
                                    "businessCode": "修改密码",
                                    "parentId": 123,
                                    "isChecked": null,
                                    "menLevel": 4,
                                    "subMenuPermissionsVO": []
                                },
                                {
                                    "id": 126,
                                    "menName": "通知中心",
                                    "path": "/setting-notice",
                                    "businessCode": "通知中心",
                                    "parentId": 123,
                                    "isChecked": null,
                                    "menLevel": 4,
                                    "subMenuPermissionsVO": []
                                }
                            ]
                        },
                        {
                            "id": 127,
                            "menName": "在线服务",
                            "path": "/setting-online",
                            "businessCode": "在线服务",
                            "parentId": 122,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": [
                                {
                                    "id": 128,
                                    "menName": "基础设置",
                                    "path": "/setting-online-base",
                                    "businessCode": "基础设置",
                                    "parentId": 127,
                                    "isChecked": null,
                                    "menLevel": 4,
                                    "subMenuPermissionsVO": []
                                }
                            ]
                        },
                        {
                            "id": 129,
                            "menName": "接入设置",
                            "path": "/setting-join",
                            "businessCode": "接入设置",
                            "parentId": 122,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": [
                                {
                                    "id": 130,
                                    "menName": "网站接入",
                                    "path": "/setting-join-website",
                                    "businessCode": "网站接入",
                                    "parentId": 129,
                                    "isChecked": null,
                                    "menLevel": 4,
                                    "subMenuPermissionsVO": []
                                }
                            ]
                        },
                        {
                            "id": 131,
                            "menName": "高级设置",
                            "path": "/setting-advanced",
                            "businessCode": "高级设置",
                            "parentId": 122,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": [
                                {
                                    "id": 132,
                                    "menName": "短信服务",
                                    "path": "/setting-advanced-msg",
                                    "businessCode": "短信服务",
                                    "parentId": 131,
                                    "isChecked": null,
                                    "menLevel": 4,
                                    "subMenuPermissionsVO": []
                                },
                                {
                                    "id": 133,
                                    "menName": "二维码名片",
                                    "path": "/setting-advanced-qrcode",
                                    "businessCode": "二维码名片",
                                    "parentId": 131,
                                    "isChecked": null,
                                    "menLevel": 4,
                                    "subMenuPermissionsVO": []
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "id": 2,
            "menName": "客服模式",
            "path": "customerMode",
            "businessCode": "customer",
            "parentId": 0,
            "isChecked": null,
            "menLevel": 1,
            "subMenuPermissionsVO": [
                {
                    "id": 102,
                    "menName": "留言",
                    "path": "儿",
                    "businessCode": "分隔符",
                    "parentId": 2,
                    "isChecked": null,
                    "menLevel": 2,
                    "subMenuPermissionsVO": [
                        {
                            "id": 103,
                            "menName": "小计成",
                            "path": "34",
                            "businessCode": "大幅度",
                            "parentId": 102,
                            "isChecked": null,
                            "menLevel": 3,
                            "subMenuPermissionsVO": [
                                {
                                    "id": 104,
                                    "menName": "76657",
                                    "path": "76868",
                                    "businessCode": "658568",
                                    "parentId": 103,
                                    "isChecked": null,
                                    "menLevel": 4,
                                    "subMenuPermissionsVO": []
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
    
    复制代码

    父组件主要代码

    
    <tree-table :menuData="menuData" :level="1"></tree-table>
    
    // 其中menuData为后台返回的数据,level为菜单层级,在menuData中有返回,这里主要是用来写样式用的。。
    
    复制代码

    子组件组件代码(一个递归组件):

    子组件全部代码(说明都在代中有注释):

    <template>
      <ul class="tree-container" :class="'level'+level">
        <li class="" v-for="(item, Index) in menuData" :key="item.id" :class="'level'+item.menLevel">
          <div class="tree-node-title" :class="'level'+item.menLevel"><label>
            <input type="checkbox" @click.stop="nodeClick(item,Index)" name="menuSelected" :checked="item.isChecked == 1 ? true : false" :value="item.id">
            {{item.menName}}-level{{item.menLevel}}
          </label></div>
          <div class="tree-childnode-container " :class="'level'+item.menLevel">
            <CheckBox :menuData="item.subMenuPermissionsVO" :level="item.menLevel"></CheckBox>
          </div>
        </li>
      </ul>
    
    </template>
    
    <script>
      export default {
        name: 'CheckBox',
        props: ["menuData", "level"],
        data() {
          return {
            checkedVal:[]
          }
        },
        created() {
    
        },
        mounted() {
    
        },
        methods: {
          nodeClick(node, index) {
          // 通过isChecked判断是否为选中状态:1-选中;0-未选中。这个字段是后端接口返回的
            if (node.isChecked == 1) {
              this.$set(node, "isChecked", 0)
            } else {
              this.$set(node, "isChecked", 1)
            }
            // 个人理解:组件每次递归调用会生成一个实例,this指向这个实例,这些实例相互独立的,所以每次的this都不一样,具体可以控制台打印看下。
            this.refreshAllParentNodes(this) // 设置父级状态
            this.refreshAllSonNodes(this.$children[index], node.isChecked);// 根据当前点击层级的状态设置自己所有子级的状态
          },
          refreshAllSonNodes(node, status) {
    
            if (node && node.$children.length) {
              node.menuData.map((meunItem, j) => {
                this.$set(meunItem, 'isChecked', status);
                this.refreshAllSonNodes(node.$children[j], status);
              })
            }
          },
          refreshAllParentNodes(node) {
            if (node) {
              var status = 0;
              var nullCount = 0;
              var fullCount = 0;
    
              if (node.menuData && node.$parent.menuData) {
                node.menuData.map((meunItem, j) => {
                  if (typeof meunItem.isChecked == 'undefined') {
                    nullCount++
                  } else if (meunItem.isChecked == 0) {
                    nullCount++
                  } else if (meunItem.isChecked == 1) {
                    fullCount++
                  }
                })
                if (nullCount === node.$children.length) {
                // 该状态说明当前点击层级和兄弟层级都没选中,所以父级也是未选中状态
                  status = 0;
                } else {
                //该状态说明当前点击层级和兄弟层级只要有一个选中,父级也是选中状态
                  status = 1;
                }
                node.$parent.menuData.map(child => {
                  node.menuData.map((meunItem, j) => {
                    if (child.id == meunItem.parentId) {
                    // 根据父级id和子级的parentId是否相等,来确定当前点击的层级的父级是哪一个
                      this.$set(child, 'isChecked', status);
                    }
                  })
    
                })
              }
              // 递归计算父级
              this.refreshAllParentNodes(node.$parent);
            }
          },
        }
      }
    </script>
    
    <style lang="scss">
      .tree-container {
        $borderColor: #ebeef5;
        width: 100%;
        padding: 0;
    
        &.level3 {
          display: flex;
          flex-wrap: wrap;
    
          & > .level4 {
            width: 25%;
            padding: 0 20px 0 40px;
          }
        }
    
        & > .level2 {
          display: flex;
          align-items: center;
          border: 1px solid $borderColor;
          line-height: 45px;
    
          .tree-node-title {
            &.level2 {
              width: 160px;
              text-align: center;
            }
    
          }
        }
    
        .level3 {
          .level3 + .level3 {
            border-top: 1px solid $borderColor;
          }
        }
    
        .tree-node-title {
          &.level3 {
            background-color: #f2f2f2;
            width: 100%;
            padding: 0 20px;
          }
    
          &.level1 {
            padding: 20px 0;
          }
    
        }
    
        .level2 + .level2 {
          border-top: none;
        }
    
        .tree-childnode-container {
          width: 100%;
    
          &.level2 {
            border-left: 1px solid $borderColor;
          }
        }
    
        input {
          margin-right: 5px;
        }
    
        label {
          cursor: pointer;
        }
    
      }
    </style>
    
    复制代码

    注意 在当前组件中使用组件本身(递归),注意图中圈出的地方,上面有两种写法

    转载于:https://juejin.im/post/5cffc27de51d45106b15fefb

    展开全文
  • 本文13323字 | 35分钟阅读 建议找个安静的地方整段时间来阅读 背景 我一直有一个反思总结的习惯,做技术到管理这些年,平时会花时间把团队管理方面的各种实践、学习和思考记录下来。经常会阅读管理和运营类书籍...

    本文主要谈谈技术TL的职责,包括团队建设与管理、团队文化、项目管理、招聘与解雇等,希望与大家共同探讨、交流。
    本文13323字 | 35分钟阅读  建议找个安静的地方用整段时间来阅读

    背景

    我一直有一个反思总结的习惯,做技术到管理这些年,平时会花时间把团队管理方面的各种实践、学习和思考记录下来。经常会阅读管理和运营类书籍,借鉴它们好的思路和执行方式,但我发现其实并没有任何一种完备的管理体系能套用到自己的团队,团队管理中我一直采用一种自底向上的过程,以更高的视角来看待团队管理中的各种事务,并且有针对性地加以改进和完善。

    技术团队管理可以分为2个方向:技术管理和团队管理,互联网公司的技术TL与传统软件公司的项目经理有很大的不同,传统软件公司的项目经理更多注重于对项目的管理包括项目任务拆解、项目范围、进度管理、风险管理等。对于技术TL不再局限于项目角度,而是对业务、团队、技术都要有深入的了解,就像黑夜里的灯塔,能够引导和修正团队成员前进的航向。综合技术和业务角度去深度思考问题,具备一定的前瞻性,并在技术领域投入持续的学习热情,向团队成员传道,补齐短板,提高整个团队的战斗力。

    技术TL不仅需要制定军规,包括流程、规范、制度等,并推动落地执行,更要减少管理过程中团队的内耗,剩下的更多精力要花在开发任务的分解分配、开发实践、技术架构评审、代码审核和风险识别上,保障系统按时交付所需的各种计划、协作、沟通、管理。

    管理大师彼得·德鲁克说:“组织的目的,就是让平凡的人做出不平凡的事。”然而,一个团队如果缺乏有效管理可能只会是一个平庸的组织。领导者的思维、能力、格局、眼光很大程度上决定了团队所能达到的高度,会给团队的工作成果带来决定性的影响。

    团队管理的核心是人,这些年带过不同的技术团队,他们的背景和技术能力虽各不相同,但管理方法上却有很多相通的地方,本文是我在管理过程中整理的一些观点和经验。

     

     

    团队建设

    我在IT和互联网行业工作了10年,创过业、做过架构,当过高管,这么些年如果你问我这么多事,最喜欢哪一样?我会说,怀着创业者心态,带技术团队做点有挑战的事情。为什么呢?因为我觉得带队能力,是人生的底层能力,拥有这种能力能让你有一种踩在地上的踏实感。

    从创业到公司高管,团队管理中所有的坑基本都踩了,一路跌跌撞撞、踉踉跄跄的趟过来了,这里我和大家分享下团队建设管理中的实践经验,其中还有很多地方做的不够好。

    团队建设中最难的是空降到一个技术团队当TL,面对一个陌生的环境和陌生团队有很多难题等着你来解决,包括对团队现有业务的快速深入了解,对团队现有流程和制度的熟悉和改进,快速建立团队成员的安全感,怎么在和领导的蜜月期内做出业绩等等。

    几年前我空降到一个技术团队当TL,本来就士气不高的团队加上我的空降,内部更是人心惶惶,生怕我接下来会有大动作。这个时候很多TL新官上任三把火,大肆的招聘和推进改革,往往把之前的旧部干将带进来。我当时没有急于这么去做,而是立足于稳定现有的团队,稳中推进各项工作,主要基于以下原因:

    • 每一项业务的开展都有很多坑和陷阱,新人很难发现,这时往往需要团队老人的支持与配合,所以建立领导者的信任关系显得格外重要,如果你排挤老人冒然带着旧部开展项目,项目一旦失败,老板的信任度就大打折扣,后面很难在公司立足,更不用谈论改造团队,发挥自己的才能了。

    • 多年带团队的经验告诉我,很多时候团队出现的问题往往不是团队成员的问题,而是领导者的问题。我认为只有好的制度、流程、规范才能造就好的团队。

    • 一朝天子一朝臣自古有之,新TL的空降大家都担心自己在团队中会被边缘化甚至开除。安稳团队避免成员动荡,也能帮你腾出更多的精力思考业务上的突破,避免你陷入信任危机,疲于奔命协调各种关系。

    经过了两个星期的摸底了解,我弄清了当时团队的一些问题和原因:

    • 团队缺少流程制度规范:产品、研发、测试部门之间配合没有合理的工作流程,比如产品的PRD没有输出标准,经常更改需求并不把修改的内容同步到产品文档中,技术的接口没有明确的规范,项目上线没有明确的上线清单,测试环节也并未按照测试用例完全执行,研发很多时候都是疲于奔命做需求,导致大家的积极性不够高。

    • 代码缺少质量评审:项目排期并不是很合理,由于项目经常被业务部门催促赶工,技术设计评审阶段往往被略过,更别说上线前的代码走查和评审了,导致上线后各种问题和bug频繁出现,使其它部门对技术部信任急剧下降。

    • 跨团队协作混乱:部门之间相互推诿再加上第二条的原因,任意业务部门人员都可以对技术人员直接领导,技术人员毫无发言权,这些都伤害了研发团队的积极性。

    针对以上问题,我制定了相对合理规范、制度和协作流程,业务部门需求必须也统一由产品输出并形成书面文档,杜绝口头需求。部门内部同产品、设计、前端、后端、测试、运维团队也形成了统一标准协作流程,下游对上游依赖方输出的工作必须有明确的标准规范,口头说的统统无效,拒绝合作。
     

    针对跨团队协作乱的情况,我特别想说明一下,研发部门在很多公司其实是业务支持部门,不承担盈利的目标,基本站在一个被动和弱势的位置,业务人员往往由于业绩压力再加上举着收入的大棒来逼迫你无条件的服从。业务部门病急乱投医临时想法形成的需求,开发过程中往往会反复修改,导致原有开发要不断返工。这样一来,部门内部再合理的规划都会让团队成员无所适从。最终没有完成预期结果部门之间便会互相推卸责任。久而久之,团队就产生了自我保护意识,凡责任尽量往别处推,不求有功但求无过。
     

    作为技术团队TL这时要想打破团队成员自我封闭和保护意识,让大家积极承担责任,我能够做的就是先自己承担责任,去协调跨部门的每一个事情,给团队成员树立一个榜样,让大家相信你是靠谱的,敢于承担失败的责任和背团队的锅,经过2-3个项目的打磨,部门内部和跨部门之间就会形成一个协作流程和规范,这时团队自然也对你产生信任。
     

    上面的团队建设的很多做法我向伯恩斯《领导力》这本书中学习了很多,他把领导力关系分为交易型和变革型,团队管理需要你和团队成员从交易性关系入手再到和大家建立起变革性关系,最终实现共同目标。如果只我们实现了单方的目标,那就是权力。如果实现的是双方的目标,那才可能是领导力。实际上和大家建立交易型关系往往只是管理,而建立变革型关系才是领导力。

     

     

    团队管理

    搞技术的人往往性格内敛,脸皮比较薄,性格高傲,不喜欢被制度限制,不善交流沟通,喜欢独立思考,契约精神较强,崇尚科学技术等等。(我这里列举的这些特征是对大多技术人员性格的抽象,一定会有例外。)如果你带领这样一个团队,却采用管理行政人员或者业务人员的方式去管理,那肯定最后会把团队整垮,还落个坏名声。那么,对于这样一群技术型人才,究竟应该怎么管理呢?

    作为一个团队的管理者,我管理方式一般采取这6个字:抓大、放小、管细。

    第一,抓大。抓大的意思就是:只管大事。执行“例外原则”:项目上的预期制,管理上的流程化,都是不错的方法。

    项目上预期制,就是确定项目执行上上什么“不算”例外。比如项目预期确定,使用多少人在多长时间完成什么样的产品输出。这些正常推进,“不算”例外,无需汇报。小组长发现质量、工期等有较大风险事,就是例外,需要汇报。

    管理流程化,就是确定管理上什么“不算”例外。比如开发流程确定,需要先进行技术设计评审然后再进行工期安排。这些流程可以一定程度提高项目质量和效率。如果某次项目开发,因为特殊情况,没有按照这个流程推进,就是例外,需要申请。

    第二,放小。放小,就是授权。授权,不是一句“这件事交给你”就完了。放小,首先要知道什么算“小”。所有在正常流程、制度、规范里的,都是小事。对于小事,TL要懂得让小组长决策。怎么做?你可以试着“不直接回答下级的问题”。

    当下级有问题时,你可以让他自己提方案。点评方案,而不是回答问题。如果直接回答问题,你觉得你在给建议,他觉得你在下命令。长此以往,这个“小”是放不下去的。

    理解了“小”,还要懂得“放”。最重要“放”的方式,是从审批制,变成备案制。你的下属要做一些“不算例外”,但是重要的决策,你可以请他把具体的做法备案。备案的意义就是通知你,如果发现有什么问题,就严格按照制度来查处。

    简而言之,“抓大放小”就是:不算例外的决策,备案;算是例外的决策,报批。

    第三,管细。很多TL都在说“抓大放小”,但常常忽视“管细”。给大家讲一个管细的例子,微软前CEO史蒂夫·鲍尔默有一次,接受各国CEO的年度汇报。巨大的屏幕上,每一页都是密密麻麻的业务数据。他利用听报告的方式来“管细”。他突然说:停,你翻到前面,这一页的这个数字,和那一页的那个数字,是矛盾的,请你解释一下。那个CEO瞠目结舌,答不上来。史蒂夫说,你根本不懂你的业务,当场就把他解雇了。

    从经理到总监,最大的不同,就是你不直接管理最一线员工了,所以,必须从“兄弟们跟我上”式的“单层管理”,过渡到“隔层管理”。记住六字真言:抓大、放小、管细,来克服“一放就乱、一管就死”的状态。

    这里的管细并不是要求TL事无巨细面面俱到。而是要求TL在关键事务和结果上把控并监督执行细节。谈到TL管理我把团队管理分为两个维度和十个模块,每个模块在两个维度之间有自己的定位,模块之间相互独立且互斥,当然这种划分并不是绝对的。下面整理了每个模块执行要点和方法。

    时间管理:时间管理重个人,项目管理重协作。时间管理是团队效率的基础。技术团队TL要起到教练的作用,时间管理方法:脑外化、番茄工作法、时间日志、GTD、团队工具集等。

    项目管理:项目管理目前有很多成熟的方法,但很难生搬硬套硬套,项目管理要根据业务发展的情况动态变化,光敏捷开发常用的队形就有“看板”,“SCRUM”,“XP”三种,而技术管理倾向于依靠规范来实现,更加稳定。项目管理要点:需求评审方法、估时方法、敏捷方法、任务管理。

    技术管理要点:技术评审规范、代码风格规范、代码管理规范、CodeReview规范、技术债务管理。这其中的CodeReview和技术债务就是典型的管细范畴。

    流程改进:技术团队管理者的工作是要做到团队管理、业务需求、技术架构三者之间的相互协同。由于多数互联网团队所做的业务都远谈不上成熟,支持它的技术团队在管理上也就不会有稳定的状态,持续改进是常态。方法包括:Lean & Kaizen、PDCA、定量分析、方案收集等。

    制度建设:按强制程度排列:制度 > 规范 > 流程。制度建设的完善程度体现着团队的严谨性与纪律性。互联网公司的工作氛围相对自由,但不代表没有规矩。尤其是与产品质量和安全相关的关键环节,必须严加把控。制度要保持最小化且持续有效,制度建设的要点:上线管理、故障响应、值班制度、加班管理等。

    目标管理:目前主流的管理体系中通常会把目标管理和绩效管理分开来看,OKR偏向目标管理,KPI偏向绩效管理。目标管理要点:目标制定、维度分解、OKR、行动循环。

    绩效管理:绩效的制定需满足可量化、可追踪、可数据化方式。绩效制定的要点:绩效设定、绩效评定、绩效反馈。

    人才招募:互联网行业的人才市场是高度自由且开放的市场,各家能提供的薪资待遇在这个有效市场中处于动态平衡状态,很难形成局部优势。最终,团队的形象和声誉才是吸引优秀人才的根本所在,人以类聚。我们在希望招募到高素质的候选人的同时,也要考虑到团队自身如何在候选人面前体现出高素质。人才招聘要点:公共形象建设、渠道维护、人才标准、面试官培养、面试流程。

    人才培养:人才培养更关注个体,团队建设更关注集体。团队一方面要做事,另一方面要育人,人才是团队的核心资产。人才培养要点:新人导入、培训体系、技能体系、导师制度、骨干培养、晋升通道。

    团队建设:团队建设功夫在平时,关键是建立好内外沟通机制。沟通充分的话文化和价值观自然能够协同一致,否则都是喊口号和空谈。团队管理要点:对内沟通、对外沟通、文化与价值观建设、知识沉淀。

    团队有合理的规范和制度后,业务流程很快就能清晰的建立起来了,骨干员工在业务上能够完全领会并达到要求,这个时候放权可以充分调动团队的自主性和创造性,多数技术人员他们喜欢被领导,不喜欢被管理。

    团队管理并不是要求管理者只做管理,很多管理层自己从不真正深入业务,缺乏对业务的深刻理解,很难发现问题的本质原因,这时他们总是寄希望于招人来解决问题,结果换了一茬又一茬人,问题永远解决不了,而且从来不深刻反思自己,其实脱离业务找不到问题本质的原因,任何的管理方法都是无效的。作为管理层,如果自己没有深入一线去发现问题、动手去解决问题,那这个团队很难有新的突破和成功。

     

    团队文化

    研发团队往往是一个比较沉闷的团队,如何把研发团队从死气沉沉变成激情活力,从固步自封到好学分享?平时经常听到Google公司讲企业文化,阿里、华为讲价值观,总觉得很牛B,高大上的东西。几个字就成为公司的核心竞争力,我们能不能自己也搞一个呢?

    团队文化是团队长期的总结和实践,也许它并不完美,但它还是能表达团队之前及现阶段的一些行为。文化推行的过程就如同花朵或生物一般,需要播种、栽培,然后才能收获。这样「长」出来的"文化",才能管人做事,深入骨髓、改变思想,才能成为公司或团队的核心竞争力。

    关于团队文化这个话题其实很泛,可以单独写一篇文章出来的。这里我主要基于团队文化以下几点,谈一下我的一些个人的看法。

     

    坦诚的力量

    曾国藩对年轻时的李鸿章说过,做人唯守一个“诚”字。坦诚是一种价值观,对于一个团队的发展来说是非常重要的。作为技术团队TL,我觉得最重要的是TL本人必须做到坦诚的态度,只有对团队坦诚,才能和团队之间形成信任,只有和团队形成了信任,才能成为一支默契的团队。

    通用电气 CEO 杰克·韦尔奇说过:什么是信任?当一个领导真诚、坦率、言出必行的时候,信任就出现了,事情就是这么简单。为什么坦诚精神能行得通?很简单,因为坦诚有化繁为简的力量!

    坦诚的性格是管理者的最基本的要求,只有TL坦诚,才能获得团队的信任,作秀式的演讲和奖励并不能够真正获得团队的心,还是需要在工作中脚踏实地一点一滴去做好最平凡普通的事情。坦诚能够让你直面自身的缺陷,有针对性地改变自己,解决团队的问题,造就一个互相信任的团队氛围。

    日常工作中对待下属要有勇气,敢于指出他们的问题,对于表现不好的员工要敢于批评和管理,例如为什么解雇你。这些谈话和冲突往往让人感到不舒服,我也承认每次谈低绩效是硬着头皮的,但是你必须有这样的勇气,坦诚不仅仅要对那些表现良好的人,还要对那些表现糟糕的人。如果你是一个结果导向的人,还是应该尽量坚持坦诚的态度,否则最终的结果可能远远偏离你的目标。

     

    培养唱反调的人

    关于员工,管理者喜欢用一个又简单又有效的做法把他们分为几类。就是用能力和态度这两个维度来给员工分类。这个分类方法有一个大漏洞,它有可能会伤害真正优秀的员工。如果你的上级在用这种分类方式,或者你自己在用,你要当心了。用能力和态度这两个维度来区分下属,有个致命的漏洞,就是怎么判断态度好坏?能力好坏还是相对比较容易判断的。可是,态度这个词太模糊了。态度好坏的标准是什么呢?又由谁来判断呢?

    举个例子来讲这个漏洞。我们假设有个技术总监,他技术和管理做得很好,但是脾气比较怪。你认为CTO该怎么对待他呢?德鲁克认为,CTO的任务就是忍受他的脾气,而且帮助其他人忍受他的脾气。但是,现实中的CTO想的跟德鲁克很可能不一样。现实中的CTO更可能怎么做呢?他更可能说这个技术总监能力强,但是态度不好。你现在发现这个分类方式的漏洞了吧。

    所以,被上级界定为态度不好的员工,不一定是真的态度不好。他有可能只是脾气不好;并不影响工作。有可能只是对上级态度不好,对工作、对其他人态度都挺好;也有可能只是喜欢提出不同意见,只不过方式比较直接。

    我看待下属也是用两个维度。一个维度是下属是否有独立的、批判性的思考,还是依赖上级替他们思考?另一个维度是下属积极主动地参与工作,还是消极被动地参与?

    这种分类方式的两个维度其实是把态度具体化了。一个是他的思考态度,是不是独立思考,另一个是看他的做事态度,是不是积极参与。这种分类方式是管理学者罗伯特·凯利(Robert Kelley)提出来 的,凯利把又独立思考、又积极参与的员工称为明星。

    这个新的分类方式把态度具体化了,界定了两种具体的态度,都是对企业有好处的态度,因此更有启发性了,也更有操作性,但是在企业界不太流行。因为上级有时不太喜欢你独立思考,你独立思考就意味着有时会不同意上级意见,上级也是人啊,也有人性的弱点,你不同意我,我怎么会 认为你是明星呢?上级会认为这样的下属是爱唱反调的人,是态度不好的员工。

    一个团队中,不一定要专门有个唱反调的人。这不太现实,这样的人一般活不下来,往往被作为态度不好的人,早早被清除了。当然,如果有这样的人,你要珍惜他。如果没有这样的人,你也要鼓励反调,至少要容忍反调。我们介绍的这个新的给员工分类的方式,最重要的结论就是要鼓励唱反调。 这是违背人的本性的,这是需要我们修炼的领导力。培养唱反调的员工其实至少有以下好处,第一,这个人说的可能是对的。第二,就算说错了,也推动自己从另一个角度再想一想。第三,公司的问题往往不是反调太多,而是反调太少,这样能鼓励一种畅所欲言的文化。

     

     

    失败了,恭喜你

    埃德蒙森把失败分为七种。分别是无视规章、粗心大意、能力不足、流程缺陷、已知风险、难料风险、探索创新。这七种失败我们把它重新分一下类,分为三组。探索创新单独成为一组,叫做好的失败。已知风险和难料风险,这两种失败归为一组,叫做正常的失败。最开始讲的四种失败,无视规章、粗心大意、能力不足、流程缺陷,把它们归为一组,叫做坏的失败。

    好的失败,是我提倡团队要主动去追求的失败;正常的失败,是难以避免的失败,所以失败了很正常;坏的失败,则是可以避免的失败,也是我在团队管理中需要重点防范的失败。

    我把失败进行了分类,你会发现失败并没有那么可怕了,可以更好的理解了“失败了?恭喜你!”这句话了。为什么失败值得恭喜?因为有些失败是好的失败,是探索创新。

    每一次失败都是善意的提醒、学习机会和成功过程,我们鼓励正常失败和好的失败,部门设有"英雄失败奖",奖励那些在探索过程中付出努力的伙伴。我的部门内部有一个黄牌制度,其中一条就是对那些在一个季度内没有任何成长且没有犯过任何错误的人会给予黄牌警告。

     

     

    建立学习型的组织

    这里我要谈的是建立学习型的组织,团队成员要尽可能地分享自己的知识和想法,大家互相学习,也通过分享能够总结自己学习过程中零散的知识点。如何建立人才梯队的,其实就是要建立学习型组织,让大家积极参与学习与分享。我带团队注重知识沉淀和经验积累,用的方法包括:

    • 书籍建设:研发部是一个技术型团队,书籍的分享和书斋的建设是很好的办法。书籍鼓励大家捐赠、分享。捐赠的书籍离开时可赎回。

    • WIKI系统:工作中所有涉及到公开的文档都必须在wiki中编写,包括不限于产品需求、技术方案、测试用例、经验总结、分享经验、流程规范等,编写的文档必须清晰明白,可用于追溯。

    • 周五分享日:每周五是部门分享日,时间定在下午17点到18点,分享的形式和内容不限,架构部和各组leader的分享是工作的一部分,其它人分享是加分项。分享要采用简单有效快的方式,鼓励直接show代码,或使用wiki来讲,这样也利于二次传播,不要一定用PPT,达到目的和起到效果即好。

    • 季度会议:季度会内容包括有新人介绍,上季度的总结,下季度的计划,新书推荐、特长展示等。季度的总结和规划,是每个leader向下级汇报。新书推荐包括介绍近期自己读过的书,以及读书的感悟与心得。

    • 反思复盘:失败或成功需进行反思和复盘,由当事人进行案例讲解并合影留念。

    • 成果分享:所有的成果展示需数据化呈现且wiki记录并公开分享,数据包括不限于性能响应时间、客户数据、热点分析、模块的SLA等。

    鼓励团队成员敢于去分享,乐于去分享,开放心态成就他人。我把团队的KPI分为责任、价值、成长。责任是自己的本质工作,而价值和成长则体现在自己的学习成长和帮助他人成长这两部分。

    当然,一开始的团队可能没有这样的意识,就需要你作为管理者强行去推动,把要求列入KPI,很认真地考核他,慢慢地,团队就会形成这样的氛围和文化。

     

    反思和复盘

    开发其实是“以终为始”,拆解任务目标,倒推执行,反复打磨达到产品的良性循环。

    复盘就像两个人下完一盘围棋后,再重新摆一遍,看哪里下得好,哪里下得不好,好的继承,不好的探索一下怎么能下的更好。

    复盘让我们不犯过去曾经犯过的错误,我在日常面试的时候,会考察候选人复盘的意识,他之前做过哪些事情,有哪些是值得借鉴的,有没有总监方法论,复盘对于个人是提升和学习,从亲身实践中总结方法提升知识。对于团队是多维度经验分享,交流和思考,利于传承经验,提升整个团队的战斗力。

    复盘要做的内容,概括起来就是一句话:执行一项任务时,我们设定了怎样的预期目标?在执行中实际发生了什么?结果如何?和目标比差异的根本原因是什么?我们从中能学到哪些经验教训?后续该如何改进?

    带着问题去做复盘,复盘才有针对性:在写复盘之前,我们需要明确一个问题,我们为什么要做这个复盘?除了学习总结外,我们有那些需要有针对性的思考,解决困惑,总结特殊动作还是业务迭代?下面这些环节的执行点可以帮助你重点分析和思考。

    • 目标与结果:回顾目标、执行结果、关键结论、差异对比、策略&计划、亮点&不足。

    • 情景再现:情景描述、资源条件、执行状态、需求设计、架构设计、流畅程度、数据分析、数据情况、推论分析。

    • 分析原因:影响要素、根本原因、关键点分析、提出假设、设问深挖、思路拓展、重新优化、案例佐证。

    • 总结规律:提炼方法、关键分析、SOP优化、经验教训、反思发现、优化方案、管理改进、约定时间、快速迭代、复盘归档。

    • 复盘工具:XMind、Axure、流程图、问卷星、excel等。

    复盘就是反思结果、反思目标、反思过程、反思前提、反思条件、反思场景、反思逻辑、反思因果关系、反思组织,对原因的深入反思是对结果负责,知其然,知其所以然,复盘首要之处就是你要愿意听批评,如果你不强迫自己走出舒适区,你将永远无法进步。

     

    关于会议

    我的团队有两个重要会议,一个是周会,另一个是分享会。工作中,不仅要有脚踏实地的奋斗,更要有诗意和远方。周会,是对上周工作的总结,目的是让我们在奔跑之余,能够短暂的驻足回顾,总结经验,品味成长。


    周会我一般定在每周一上午进行,主要讨论工作问题、项目进度等事宜,需在wiki上提交会议纪要,全员可查看。每周的周会由部门内部小伙伴轮流主持和记录。周会主持人需站在部门负责人的角度,对汇报人员提出质疑或建议,站在整个研发中心的角度去思考,这样可以培养每个人的全局观,减少本位主义和平时工作中不必要的冲突,提高了管理人员的组织协调力。

    周会要求部门内部能了解大家的进展、心得、计划,周会内容至少包括三部分:本周进展、个人总结、下周计划。

    • 本周进展,本周具体的完成的任务内容,按照优先顺序排列,方便他人了解你的进展,成果尽量可数据化。

    • 个人总结,把一周40个小时工作中,遇到的问题和挑战,自己的各种心得体会,写下来分享给大家,共同进步。

    • 下周计划,为自己接下来的具体工作内容制定一个计划,包括新版本、新需求,修bug、做调研等。

    工作日每周五天,这五天中我会安排每一天都是不同的日子,周一例会日、周二为发布日、周三无会日、周四下午茶、周五分享日。每周五是部门分享日,时间会定在下午17点到18点,分享的形式和内容不限,架构部和各组leader的分享是工作的一部分,其它人分享是加分项。分享要采用简单有效快的方式,鼓励直接show代码,或使用wiki来讲,这样也利于二次传播,不要一定用PPT,达到目的和起到效果即好。

    作为研发团队,一定要注意做好技术分享,这样才能提高整个团队的研发能力,让大伙都处在较高的水平线上一同进步,一同去研发更高新的技术。很多小伙伴其实抵触分享,一方面是担心自己的组织能力不够,导致分享的效果差,另一方面是担心自己技术能力和业务能力不够,在会上被点住出丑,或者自己的分享有偏差,误导了他人,影响了自己的声誉。总之是一阵的纠结和抗拒。其实分享是很好的学习方法,你一旦要分享了,就知道,不是你一个人知道你在学习,你就会更加认真全面的去学习知识,会带着一个驱动力的学习,效率倍增。

     

    项目管理

    贝索斯有一个经典的管理哲学:如果一个团队的人数多到两个披萨都喂不饱,那么这个团队人就太多了。

    我们生活在一个丰富多彩的世界,而世界庞杂繁复的一面对于我们的影响并不总是正面的。商业世界中的规则和需求往往杂乱无章,更多的功能、更多的资源、更多的人、更多的办公室已经成为一种常态,这使得这个时代几乎所有的东西变得「越来越多」。我们开始慢慢忘记少即是多这件事情。

    当你带研发团队做项目时你会发现随着人员规模的增加,团队成员的平均生产力会越来越低,所以我带项目通常把项目需求切割的特别小,保证再7个人的团队2周内可以上线。既保证效率,也减少项目试错成本。

    项目管理中我认为重要的第二点是代码质量管理,我身边经常会听到很多朋友抱怨,说他无法把握整个项目组成员的代码质量。这也是所有项目组普遍存在的问题吧,它通常表现为以下几个问题:

    • 新手:任何项目组成员都不可避免地出现新手,他们往往是刚刚从大学毕业的学生。这些新手由于开发时间太短,技术不成熟,没有形成良好的开发习惯,所以编写代码质量较差,问题很多。他们常常成为项目组的“鸡肋”,用多了项目质量无法得到保证,不用则又人手不够。

    • 人员变动:一个维护时间稍长一点儿的项目,人员变动是在所难免的。老员工被调动到其它项目去了,由新员工来接替他们的工作。在我带的项目组中,人员调动达到了90%。新员工在接替老员工进行代码维护,甚至继续进行新的开发的时,由于对原有代码以及设计思路理解的偏差,也会出现大量的低劣代码。

    • 不规范的代码编写:即使除去以上两个问题的影响,项目组成员编写的代码同样会出现问题。在项目开发之初,我们往往会制定一个代码编写的规范,但在项目开发过程中,许多成员往往会忽视这些代码规范而进行随意的编写。随意地代码编写会降低代码的可读性、可维护性和易变更性。
       

    上述问题反映了代码复查的重要性,但为什么仍有很多团队没有进行代码复查呢,因为代码复查是有代价的,甚至有时是巨大的,主要原因有:

    • 复查者要承担审查后代码出问题的责任,发现问题会要求被审查者限期整改,可能影响工期。

    • 审查后的代码可能还会被反复修改,导致复查者需要反复审查。

    • 对于大需求上线的项目,复查代码时间较长且需要深入理解产品和业务需求。

    所以上面我讲到的第一点,小团队短周期的项目在这里优势就凸显出来了,这时每个小组长可以去指导其他成员的设计,并且复查他们的代码。最终,他要对小组所有成员的代码质量负责,由技术经理或架构师进行抽查,检验其整体情况。

    第三点我谈谈进度管理,在业内流经常听到这样一句令人心酸的话:“规划规划全是鬼话,计划计划全是空话”。项目进度的延迟总是在快到计划结束的时刻暴露出来,结果是谁也不知道到底什么时候才能够结束项目,如何确保项目进度一直是困惑项目管理的难题。项目进度控制是项目管理工作中的重要一环,也可以说是最艰难的工作之一。在项目开发中项目进度失控受到很多因素的影响,包括项目进度估算偏差、前松后紧对项目进度缺乏有效监管和控制、没有尽早发现项目风险、人员流动性大等等。

    项目启动时让项目中的团队成员参与到项目时间计划表的讨论中会更加有效,因为这将确保所有项目成员的权益。一人计短二人计长,TL通过这种方式可以避免出现考虑问题不到位的情况,以及对计划中出现的可能问题进行偏差纠正。

    在项目各阶段设置一个里程碑,这样就提供了很大的机会来检查项目是否在按照正常的轨道进行,以及是如何进行的。通过创建项目里程碑,可以让项目团队成员始终保持专注和对阶段性任务完成的积极性。

    在做日程计划的时候,任务的时间分配可以参考历史信息或者其他人的经验,当团队成员内部讨论达成共识后,根据进度进行任务分解和资源投入,在做日程计划的时候需要花点时间去做评估,因为后续想要进行更改将会是一个艰难的挑战,所以一定要在前期把时间评估正确。

    不管项目最初是如何精心的创建项目范围以及确定项目的起始时间和结束时间,这些都是基于安全的假设和规范的操作。但在实际过程中,项目前进的道路会出现令人猝不及防的变化,为了适应这些变化,明智的做法是留出一些额外的时间,这样在项目到达截止日期前会有一定的缓冲余地。

    完成日程计划表的定制后,给项目团队成员分配任务,不要认为项目成员会有100%的生产率,因为项目成员总是会被文书工作、会议、临时性的沟通打断,这些都需要额外的时间,所以最好把它们包含在你的进度估算中。一旦项目成员被分配任务,那么整个日程安排就应该进行审查看是否存在冲突,这也确保了每个成员希望按照个人的情况来实现在这个项目的动机和目标。

     

    招聘与解雇

    人才永远是一个公司的核心竞争力,好的产品离不开好的团队,企业间的竞争归根结底是人才的竞争,因此,招聘永远是第一位的。人才招聘和解雇尤其对于一个新上任的技术TL,都是一个很大的挑战,接下来我们重点讨论这两个话题。

    招聘

    在搭建技术团队招聘前,要先明确所搭团队的类型,一般来说有三种不同类型的技术团队,即项目驱动型、业务驱动型和技术驱动型,不同类型的技术团队在招聘时也有很大的不同,比如技术驱动型团队你可能需要一个在中间件、语言功底非常深厚、有大局观的人,业务驱动型的团队可能需要有业务sense,并且具备良好技术和业务架构能力的人。

    标准化的招聘流程有助于我们发现&筛选人才,同时也能够换个角度审视我们自己。

    ★ 招聘规划:

    • 根据搭建团队的目标,做好招聘计划根据公司战略目标,拆解到团队自身的定位,切忌因临时短暂的项目招人设岗,这样招聘进来的候选人会没有存在感,长时间下来会导致新人离职。

    • 确定招聘需求(定岗定责),列出每个岗位的职责、需要具备的技能及其他要求。招聘需求归根结底是需要什么样的人,与据整体业务和组织发展匹配。

    • 合理利用人才招聘渠道,从我自身的经历来看,好的人才很难短时间招聘到岗,往往高端的岗位朋友推荐更可靠一些,所以关键时刻TL的靠谱程度就显得非常重要了。

    ★ 人才流程:

    • 简历筛选,筛掉达不到标准的简历,甄选出符合要求、有亮点的简历,一般看三点:学历、履历、项目经验。

    • 电话面试,对于时间上不方便到场的候选人,可以先进行电话面试,电话面试可以先考察候选人的基本情况,再约现场面试。

    • 到场面试,现场面试考察候选人的基本技能、语言基础、算法 & 数据结构、逻辑思维、项目经验,这些考察点可以看出候选人项目决策过程、架构设计、方案选型等,也可以设计open类型题目来探讨。

    • 考察软性能力,研发人员的软技能通常可以看责任心、踏实性、积极性、聪明程度、勤奋程度、技术兴趣、沟通表达和其他亮点,其中每次换工作的决策过程,平时关注技术的兴趣度,最成功/最失败/最自豪/最遗憾的事情是什么?上一份工作中最大收获/印象最深的事情是什么?等这些都是很好的问题。

    一个团队的健康发展,最重要的是核心的是人,所以招聘工作必须谨慎,一旦有人加入就等于站上了同一艘船,尤其部门团队的伙伴,每天陪伴的时间比和家人还长,其中的纠结、痛苦、欢喜都要一起面对。当面对候选人犹豫不决时,我经常会问自己一个问题:如果不发offer,会不会感觉很可惜?特别注意的是,整个面试过程中我们应该不断的挖掘对方的亮点,亮点是决定的好依据。

    作为技术TL最成功的是招到比你更优秀的人,你不需要担心自己会不会被取代,一是成就个人和成就团队,作为TL应该抱着如何成就团队的发展思路,不能让自己成为天花板,本身技术就不应该是你最擅长的事情!

     

     

    解雇

    我的团队有一个不成文的规定,就是没有亲自解雇过下属的经理岗以上职位的人,是不能进行招聘决策人的。如果你没有开除或解雇过员工,可能很难算上真正合格的管理者,因为只有经历过解雇或开除员工的人,才能体会招聘需要有多谨慎,解雇员工有多么的为难。

    当出现触犯红线的员工,尤其是不认可团队价值观的同学,会把一些负面情绪、行为传染到其它成员,这个时候做TL需要当机立断采用合适的方法让员工离开。在解雇这件事情上,高级管理者不要过于犹豫,为了一两个人最后影响整体团队的士气反而得不偿失。当然,对于初犯错误的员工要给予改正的机会,并指导他们成长。

    每个技术团队都有自己的KPI考核,通过KPI对达不到预期的人员进行淘汰,也是一种方式。对于新上任的TL解雇团队成员的确是一个很大的挑战,因为人性本善,朝夕相处必定有感情,也付出了很大的沉没成本。但作为团队的领导,我们要克服自身的弱点,站在组织或公司层面上来看问题,其实组织和公司的打怪升级,人员更替是常态,平常心看待就好。

     

     


                                                                                                      · end · 

     

    推荐阅读:

    跃迁成为一个高手的技术,值得收藏

    精进成一个很厉害的人,这七个纬度你知道几个?

    你为什么总被广告骗?看懂这些套路就不愁!!!

    绩效篇 | 从创业到上市公司高管,我愿意手把手教你带队经验!

     

                                                      一周一篇

                                             记录杂事、感悟和心得

                        


    每一个人眼中,都有自己理想管理者。你认为优秀的技术TL身上有哪些特质?欢迎大家留言讨论。

    展开全文
  • 一年的假期光了,有面试通知请不出假,偏偏专家们还站着不腰疼地劝求职者们一定要“骑驴找马”,熬到发了年终奖再走。可好不容易争取到的面试机会就“时不我待”地飞走了,这还能不能让人相信专家、相信攻略了? ...
  • 然后把入职的各个环节工作进行系统梳理,包括从招聘到通知入职、报道、入职培训、与用人部门交接等环节,充分考虑到新人的感受和内心需求,进行系统规划和介绍,让新人感受到被尊重、被重视,让他了解他想了解的内容。...
  • 产品业务流程1

    2010-11-07 01:09:00
      上级下级请求媒体流 现在MC已经建立了自己专门的发送线程 如果其他线程需要发送消息(TCP),就抛到该线程进行处理 发送线程首先根据对应目标的ip,检索出对应的socket 如果找不...
  • 还有其上级下级、合作方的评价。”对方是否愿意配合?Carol说,她会请候选人自己提供一些名单和联系方式,“但是我出具的背景调查不会完全是候选人提供的名单,我会参考这些人的意见,也会通过自己渠道找到其他前...
  • 在计算机产业发展的70年时间里,每一次的 IT 革命,无不带来:更低廉的价格、更完善的功能、更便捷的使用、更广阔的市场! 大数据经过10年发展,现在已经到了一个重要的分水岭阶段:通用性和兼容性能力成为大数据...
  • 数据分析侠A的成长故事

    万次阅读 多人点赞 2016-03-09 10:46:40
    数据分析侠A的成长故事面包君 ...那年他实习,选择了一家国内一线梯队的电商公司,HR问道想选择什么岗位,而他本人自己也比较困惑,说数据感兴趣。而恰好那年公司打算成立一个数据部门,就把同学A分配到了市场部的数
  • 15类一面试就知道不靠谱的公司

    万次阅读 多人点赞 2018-05-07 15:46:29
    下级面试上级,基本上这次候选人就挂了。 10、社保一年之后缴纳/社保你自己承担。 如果不是初创公司,已经运营若干年的,这些你必须警惕。有家业界还算比较出名的公司,竟然让员工承担所有社保扣缴部分,弄...
  • C++对象模型

    2017-06-30 13:20:53
    对于使用VC++的程序员来说,还应该了解一些VC++对于C++的诠释。 Inside the C++ Object Model虽然是一本好书,然而,书的篇幅多一些,又和具体的VC++关系小一些。因此,从篇幅和内容来看,译者认为本文是深入理解C++...
  • 制定计划前要决策做什么,找合适的人来做,并告诉组员怎么去做。 你的决策需要有人去执行。 也需要跟大家商量,集思广益,自己的决策也可能是错误的, 一意孤行也许会众叛亲离。 千万不要相信你能统一大家的...
  • Apache 的 httpd.conf 详解 【转】

    千次阅读 2017-02-23 15:35:01
     由于Apache一个目录的访问控制设置是能够被下一级目录继承的,因此根目录的设置将影响到它的下级目录。注意由于AllowOverride None的设置,使得Apache服务器不需要查看根目录下的访问控制文件,也不需要查看...
  • 完美搞定,看似简单的东西,其实里面包含很多逻辑判断:多级菜单的显示位置,显示大小,如何通知上级菜单自己被销毁,怎么发送通知,何时销毁 自己,应该显示那个下级菜单,怎么保存子菜单的信息。实在搞不下去我...
  • c++继承中的内存布局

    千次阅读 2011-08-09 16:31:57
    今天在网上看到了一篇写...看了之后获益良多,现在转在我自己的博客里面,作为以后复习之。 ——谈VC++对象模型 (美)简.格雷 程化 译 译者前言 一个C++程序员,想要进一步提升技术水平的话,应该多了解一些语言
  • 某工业企业公共服务平台架构设计

    千次阅读 2011-01-26 14:51:00
    的集群设计,以避免单服务的单点故障,并在集群设计的时候考虑故障切换和负载均衡的设计属性,包括链接上级服务和下级服务的链路均衡并采用适合的链接方式,如采用 JDBC/OCI POOL 方式及含有 LB/HA ...
  • 第七章 引为前车之鉴

    千次阅读 2012-11-07 19:34:39
    常听到刚进入工商界的年轻人,亲友、家人发牢骚:“我那个主管(或老板)简直不通事理,只知作威作福,十足的草包一个,跟着这种人做事,真是倒了八辈子的霉!...在任何一个行业中,下级对上级不满都是常有的事,假如
  • 企业老板来说,无疑想给为自己带来最大利润的员工以最大奖励,但又要照顾到其他员工的情绪,要奖励最优秀的员工,还是平均照顾到每个员工,每个老板都有自己的选择,每个员工也都有自己的抱怨。 奖金对于员工来说...
  • 有段时间没写文章了,最近沉迷Rust,无法自拔,锈儿有毒;这真是门非常有趣的语言,很多地方的设计...大家如果阅读过一些开源框架的源码,可能会发现其中数不尽的抽象类,设计模式拈手而来,在功能框架中,可以使用设.
  • 前言 有段时间没写文章了,最近沉迷Rust,无法自拔,锈儿有毒;这真是门非常有趣的语言,很多地方的...大家如果阅读过一些开源框架的源码,可能会发现其中数不尽的抽象类,设计模式拈手而来,在功能框架中,可以使用
  • 文章目录 前言 一、 基本概念 1.1 产生的背景 1.2相对进程, 使用多线程的好处 1.3 进程和线程的区别 1.3.1 进程的概念 1.3.2 线程的概念 1.4 上下文切换 二、 Java多线程创建方式 2.1 多线程创建方式 2.1.1 继承...
  • 上面的业务进行分析,可以明确一些事 这个业务是一个链式的,有着明确的方向性:单向,从头到尾指向 业务拆分开,可以将一个弹窗作为单颗粒度,一个弹窗作为节点 上级的业务节点可以对下级节点拦截(点击取消,...
  • 5、标签支持像脑图那样分解,并且选中上级标签后,会同时显示所有下级标签对应的任务事项,onimifocus做到了这个。举例例子,你有一个标签是“朋友”,朋友里面可以细分出朋友A和朋友B,你可以只看朋友A相关的事项...
  • 第05章 进程管理解析 操作系统内核的三大核心功能的最后一个是进程管理。本章将从进程描述符等数据结构开始,主要介绍进程的创建、进程的销毁、进程的调度策略和切换过程等内容。 5.1 进程描述符 进程管理中最重要的...
  • 第05章 进程管理解析 操作系统内核的三大核心功能的最后一个是进程管理。本章将从进程描述符等数据结构开始,主要介绍进程的创建、进程的销毁、进程的调度策略和切换过程等内容。 5.1 进程描述符 进程管理中最重要的...
  • 医院信息系统基本功能规范---社区卫生服务接口功能规范第一条 《社区卫生服务接口功能规范》是协助医院与下级社区卫生服务单位进行信息交换的计算机应用程序。其主要任务是跟踪病人,提高出院后服务质量,为社区病人...
  • 即学即英语会话词典

    千次阅读 2008-03-17 13:59:00
    futon原本是日文,现在英文中也逐渐使用,意为“被子”。 Let’s put the futon away. (把被子收起来吧。) 昨天晚上你打呼噜了。 You were snoring last night. *snore“打呼噜”。 You were snoring last ...
  • 公示并不只是把确定好的OKR通知全员,而是要就为什么定了这些目标,实现这些目标公司的意义,一起完成这些目标需要大家分别做什么等问题做详细的沟通,确保大家目标的理解一致。 公示在公司的公共服务器上,每个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 761
精华内容 304
关键字:

上级对下级用通知合适吗